I've always been fascinated by Malbolge programming language, which is that hard:
Malbolge was so difficult to understand when it arrived that it took two years for the first Malbolge program to appear. Indeed, the author himself has never written a single Malbolge program.[1] The first program was not written by a human being: it was generated by a beam search algorithm designed by Andrew Cooke and implemented in Lisp.[2]
( https://en.wikipedia.org/wiki/Malbolge )
In Russian:
На следующем витке углубления потаенного знания в моду вошла эстетика чистого охренения. На языках той поры писать было невозможно – по определению; они стали крайним проявлением недружелюбности к программисту. Принцип, заявленный еще при разработке INTERCAL'а («чтобы все вас уважали, надо заниматься тем, что никому не понятно») здесь был не просто поставлен во главу угла – возведен в идеал. На переднем крае – язык Malbolge. Такое название для языка программирования (Malebolge, «Злые Щели» (в переводе Державина) – восьмой круг Дантева Ада (Inferno)) его автор Ben Olmstead объясняет безыскусно: «хотелось сделать максимально адский (Infernal) язык из всех возможных». В общем и целом, это вполне удалось: потребовалось всего два года, чтобы создать первую работающую программу на Malbolge (более того, эта программа была не написана собственноручно программистом, а «найдена» специальной исследовательской программой на языке Lisp). Этой первой программой стал классический «Hello world» – вот такой: (=<:9876Z4321UT.-Q+*)M&%$H"!~}|Bzy?=|{z]KwZY44Eq0/{mlk** hKs_dG5[m_BA{?-Y;;Vb'rR5431M}/.zHGwEDCBA@98\6543W10/.R,+O< Стоит заметить, что Malbolge взял очень важную планку: эзотерические языки программирования стали объектом исследования. «Как написать работающую программу на Malbolge» – это была задачка, об которую очень и очень стоило поломать голову; золотыми буквами в историю языка вписаны имена Энтони Йонаса, опубликовавшего несколько работающих программ, но не раскрывшего секрета их написания, Лу Шеллера, проведшего криптоанализ (sic!) языка, Томаса Вергзановски, создавшего генератор несложных, но работающих программ... (...которые в несколько раз больше аналогичных программ Энтони Йонаса, по сию пору хранящего свои секреты.) Подобно Malbolge, «вещью в себе», то есть объектом, а не инструментом изучения, стали: язык Thue, основанный на исчислении Thue, созданном одноименным норвежским математиком; ALPACA – язык клеточных автоматов (игру «Жизнь» помните? – натуральный клеточный автомат); линейка языков Smetana-SMITH-Muriel. Три последних (за авторством уже известного нам Криса Пресси) замечательны тем, что довольно вычурная идея самомодификации кода положена в основу любого действия: единственный способ управления выполнением (вместо всяких там циклов-условий-переходов) – скопировать свой собственный код «вперед», чтобы он выполнился еще раз. Писать такие программы мучительно неприятно; зато для раздвижения границ сознания концепция Сметаны или Туэ – похлеще диэтиламида лизергиновой кислоты. Впрочем, все эти «игрушки» меркнут перед «воплощенной сложностью» в лице Malbolge – и в благодарной памяти потомков он остается единственным вечноживущим языком из категории «чистого охренения».
( https://rsdn.org/article/philosophy/languages.xml )
More links: https://esolangs.org/wiki/malbolge, http://www.acooke.org/malbolge.html, http://www.lscheffer.com/malbolge.shtml.
My Simulated Annealing (SA) searcher can find a couple of 13-byte program that prints "Hi" (way shorter than the ones that can be generated automatically here):
''B$@"]!<54XE
D=%$$9]76Z:WE
Check with the online interpreter: http://malbolge.doleczek.pl/.
It takes ~10 minutes on my venerable Intel Xeon E3-1220 3.10GHz (remember, this is Python).
What about bruteforce? log2(6^13) = ~33 bits. Still possible. But in my case, interpreter() function has to be called only 400 times.
# requires https://github.com/perrygeo/simanneal library # Malbolge interpreter has been copypasted from https://github.com/Avantgarde95/pyMalbolge and reworked # interpreter: http://malbolge.doleczek.pl/ from __future__ import print_function from __future__ import with_statement import math import random from simanneal import Annealer import sys TABLE_CRAZY = ( (1, 0, 0), (1, 0, 2), (2, 2, 1) ) ENCRYPT = map(ord, '5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72FhOA1CB'\ '6v^=I_0/8|jsb9m<.TVac`uY*MK\'X~xDl}REokN:#?G\"i@') OPS_VALID2 = (4, 5, 23, 39, 40, 62, 68, 81) OPS_VALID = (4, 5, 39, 40, 62, 68) # without 23 (read), 81 (end) POW9, POW10 = 3**9, 3**10 # -------------------------------------------------- def rotate(n): return POW9*(n%3) + n/3 def crazy(a, b): result = 0 d = 1 for i in xrange(10): result += TABLE_CRAZY[(b/d)%3][(a/d)%3] * d d *= 3 return result def initialize(source, mem): i = 0 for c in source: if c == ' ' or c == '\n': continue if (ord(c)+i) % 94 not in OPS_VALID2: print ('Invalid character in the source file:', ord(c)+i, ' at: ', i) sys.exit(1) if i == POW10: print ('Source file is too long') sys.exit(1) mem[i] = ord(c) i += 1 while i < POW10: mem[i] = crazy(mem[i-1], mem[i-2]) i += 1 def interpret(mem): written="" steps=0 a, c, d = 0, 0, 0 while 1: if mem[c] < 33 or mem[c] > 126: return written, steps v = (mem[c]+c) % 94 if v == 4: # jmp [d] c = mem[d] elif v == 5: # out a #write(chr(a % 256)) #flush() written=written+chr(a % 256) #elif v == 23: # in a # a = ord(read(1)) elif v == 39: # rotr[d]; mov a, [d] a = mem[d] = rotate(mem[d]) elif v == 40: # mov d, [d] d = mem[d] elif v == 62: # crz [d], a; mov a, [d] a = mem[d] = crazy(a, mem[d]) elif v == 68: # nop pass elif v == 81: # end return written, steps else: pass if mem[c] >= 33 and mem[c] <= 126: mem[c] = ENCRYPT[mem[c] - 33] c = 0 if c == POW10-1 else c+1 d = 0 if d == POW10-1 else d+1 steps=steps+1 return written, steps # -------------------------------------------------- def calc_fitness(state): mem = [0] * POW10 if initialize("".join(state), mem)==False: return 0 written, steps = interpret(mem) need="Hi" # bonus: 10 for each written character fitness=len(written)*10 # bonus: 50 if only 2 characters written if len(written)==2: fitness=fitness+50 # bonus: 50 if characters are different if len(written)>=2 and written[0]!=written[1]: fitness=fitness+50 if written==need: print ("found!") print ("".join(state)) exit(0) # bonus: 100 if character is what we need if len(written)==1: if written[0]==need[0]: fitness=fitness+100 if len(written)==2: if written[1]==need[1]: fitness=fitness+100 return -fitness class TestProblem(Annealer): # pass extra data (the distance matrix) into the constructor def __init__(self, state): super(TestProblem, self).__init__(state) # important! def move(self): while True: #if (ord(c)+i) % 94 not in OPS_VALID: idx = random.randint(0, len(self.state) - 2) # do not touch the last END ins a=random.choice(OPS_VALID) if a<idx: a=a+94 if a-idx<32: continue if a-idx>127: continue t=chr(a-idx) if t!=' ' and t!='\n': self.state[idx] = t return def energy(self): return calc_fitness(self.state) if __name__ == '__main__': init_state=[] pgm_len=13 # fill with NOPs: for i in range(pgm_len): init_state.append(chr(68-i)) # the last ins is END: init_state[pgm_len-1]=chr(81-(pgm_len-1)) test = TestProblem(init_state) test.steps = 4000 # since our state is just a list, slice is the fastest way to copy test.copy_strategy = "slice" state, e = test.anneal() print() print("%i energy:" % e) pgm="".join(state) print (pgm) mem = [0] * POW10 initialize(pgm, mem) print (interpret(mem))
( https://github.com/DennisYurichev/yurichev.com/blob/master/blog/malbolge/SA_Malbolge.py )