html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Мультиязыковые квайны из песочницы

Прочитал статью «Эстафета из 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 вычисляется заново.

Апдейт.

Посмотрел на дискуссию в комментах и понял, что нужно объяснить получше.
Квайноподобную конструкцию (здесь и далее речь только о языках, где можно разделить данные и код) можно поделить на две части:
1) сегмент данных (важный момент, эта часть остаётся незаполненной до того момента, когда код будет завершён, после этого он кодируется).
2) сегмент кода
Сегмент данных — это некий шифр, который можно расшифровать двумя способами, в результате расшифровки первым способом получится строковое представление собственно сегмента данных, при расшифровке вторым способом получится строковое представление сегмента кода. Объединив результаты этих расшифровок, мы получим строку, в которой содержится весь исходный код программы.
В вышеприведённом примере, такая строка это - 'data = %s'%`data`+chr(10)+data.
'data = %s'%`data` — расшифровка дающая сегмент данных, data — расшифровка дающая сегмент кода, ну и chr(10) — переход строки между ними.
А дальше, после того, как у нас в руках есть эта волшебная строчка, мы можем сделать с ней всё что захотим. Если мы её просто распечатаем, получим обычный квайн:

data = "l = 'data = %s'%`data`+chr(10)+data\nprint l"
l = 'data = %s'%`data`+chr(10)+data
print l


Если перевернём, получим программу, которая печатает свой текст задом-наперёд:

data = "l = 'data = %s'%`data`+chr(10)+data\nprint l[-1::-1]"
l = 'data = %s'%`data`+chr(10)+data
print l[-1::-1]


Можем написать программу, которая печатает своё шестнадцатеричное представление:

data = "l = 'data = %s'%`data`+chr(10)+data\nprint ' '.join([hex(ord(e)) for e in l])"
l = 'data = %s'%`data`+chr(10)+data
print ' '.join([hex(ord(e)) for e in l])


В общем можем написать программу, которая печатает свой код после любой трансформации (ну или цепочки трансформаций, как в нашем случае). «Шифр» не обязан быть именно внутренним питоновским представлением строк, можно зашифровать например в виде ascii-кодов или ещё как-нибудь и соответствующем образом изменить процедуру расшифровки:

data = [108, 32, 61, 32, 39, 100, 97, 116, 97, 32, 61, 32, 37, 115, 39, 37, 100, 97, 116, 97, 43, 99, 104, 114, 40, 49, 48, 41, 43, 39, 39, 46, 106, 111, 105, 110, 40, 91, 99, 104, 114, 40, 101, 41, 32, 102, 111, 114, 32, 101, 32, 105, 110, 32, 100, 97, 116, 97, 93, 41, 10, 112, 114, 105, 110, 116, 32, 108]
l = 'data = %s'%data+chr(10)+''.join([chr(e) for e in data])
print l

Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

1

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • habrahabr.ru
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции