Прочитал статью «Эстафета из 50-ти квайнов». Действительно, человек написал потрясающую штуку, колоссальный труд, настоящее произведение искусства. Но по комментам судя, многие не понимают, как подобные вещи делаются и полагают их чем-то на грани, если не за гранью, человеческих возможностей, особенно много эмоций было по поводу эзотерических языков (Brainfuck, Unlambda, Whitespace) в списке.
В этой статье я попытаюсь объяснить, как подобные квайны пишутся.
Вот код на питоне, который генерирует код на брейнфаке, который генерирует код на анлямбде, который генерирует первоначальный код на питоне:
data = 'def brainfuck(st): return "".join(["+"*ord(c)+".>" for c in st])ndef unlambda(st): return "`r"+"`"*len(st)+"".join(["."+e for e in st])+"i"nprint brainfuck(unlambda('data = %s'%`data`+chr(10)+data))'
def brainfuck(st): return "".join(["+"*ord(c)+".>" for c in st])
def unlambda(st): return "`r"+"`"*len(st)+"".join(["."+e for e in st])+"i"
print brainfuck(unlambda('data = %s'%`data`+chr(10)+data))
Я попытался сделать код максимально понятным, тем не менее, на всякий случай, пройдусь по нему построчно.
В первой строчке закодированы все следующие строки в питоновском представлении. эта строчка пишется последней, после того как весь програмный код написан, он кодируется.
>>> data = 'def brainfuck(st): return "".join(["+"*ord(c)+".>" for c in st])ndef unlambda(st): return "`r"+"`"*len(st)+"".join(["."+e for e in st])+"i"nprint brainfuck(unlambda('data = %s'%`data`+chr(10)+data))'
>>> print data
def brainfuck(st): return "".join(["+"*ord(c)+".>" for c in st])
def unlambda(st): return "`r"+"`"*len(st)+"".join(["."+e for e in st])+"i"
print brainfuck(unlambda('data = %s'%`data`+chr(10)+data))
Соответственно, текст программы целиком можно представить следующей строкой:
'data = %s'%`data`+chr(10)+data
Функция unlambda получает текст и возвращает программу на unlambda его печатающую.
Функция brainfuck — то же самое для brainfuck.
Ну и соответственно
brainfuck(unlambda('data = %s'%`data`+chr(10)+data))
это строка, представляющая из себя программу на Brainfuck, выводящую программу на Unlambda, выводящую исходную программу на
Питоне.
В цепочку легко добавлять новые языки, для каждого языка пишется функция, которая получает строчку и возвращает программу на этом языке, которая эту строчку печатает, затем эта функция добавляется к строчке вывода, ну и соответственно data вычисляется заново.
Автор: gromozeka1980