Пользователь
81,4
рейтинг
16 июля 2013 в 10:43

Разработка → Эстафета из 50-ти квайнов



Квайн — компьютерная программа, которая выдаёт на выходе точную копию своего исходного текста. Японский рубист Юсукэ Эндо (Yusuke Endoh) создал нечто невероятное. Quine Relay — программа на Ruby, которая генерирует код программы на Scala, которая генерирует код программы на Scheme, которая генерирует… и так далее на 50-ти языках программирования, пока программа на REXX снова не генерирует изначальный код на Ruby.

Для проверки нужно сначала установить в системе все необходимые окружения. Под Ubuntu это можно сделать такой командой:

$ apt-get install algol68g bash beef boo clisp clojure1.4 coffeescript \
  fp-compiler g++ gauche gawk gcc gforth gfortran ghc gnat gnu-smalltalk \
  gobjc golang groovy icont intercal iverilog jasmin-sable llvm lua5.2 \
  make mono-devel mono-mcs nodejs ocaml octave open-cobol openjdk-6-jdk \
  parrot perl php5-cli pike7.8 python r-base regina-rexx ruby1.9.3 scala \
  swi-prolog tcl8.5 ucblogo valac

Запускаем программу с каждым интерпретатором/компилятором, по очереди.

$ ruby QR.rb > QR.scala
$ scalac QR.scala && scala QR > QR.scm
$ gosh QR.scm > QR.bash
$ bash QR.bash > QR.st
$ gst QR.st > QR.tcl
$ tclsh QR.tcl > QR.unl
$ ruby unlambda.rb QR.unl > QR.vala
$ valac QR.vala && ./QR > QR.v
$ iverilog -o QR QR.v && ./QR -vcd-none > QR.ws
$ ruby whitespace.rb QR.ws > QR.adb
$ gnatmake QR.adb && ./QR > QR.a68
$ a68g QR.a68 > QR.awk
$ awk -f QR.awk > QR.boo
$ booi QR.boo > QR.bf
$ beef QR.bf > QR.c
$ gcc -o QR QR.c && ./QR > QR.cpp
$ g++ -o QR QR.cpp && ./QR > QR.cs
$ mcs QR.cs && mono QR.exe > QR.clj
$ clojure QR.clj > QR.cob
$ cobc -x QR.cob && ./QR > QR.coffee
$ coffee QR.coffee > QR.lisp
$ clisp QR.lisp > QR.fs
$ gforth QR.fs > QR.f
$ gfortran -o QR QR.f && ./QR > QR.f90
$ gfortran -o QR QR.f90 && ./QR > QR.go
$ go run QR.go > QR.groovy
$ groovy QR.groovy > QR.hs
$ runghc QR.hs > QR.icn
$ icont -s QR.icn && ./QR > QR.i
$  ick -b QR.i &&  ./QR > QR.j
$ jasmin QR.j && java QR > QR.java
$ javac QR.java && java QR > QR.ll
$ llvm-as QR.ll && lli QR.bc > QR.logo
$ ucblogo QR.logo > QR.lua
$ lua QR.lua > QR.makefile
$ make -f QR.makefile > QR.il
$ ilasm QR.il && mono QR.exe > QR.js
$ nodejs QR.js > QR.m
$ gcc -o QR QR.m && ./QR > QR.ml
$ ocaml QR.ml > QR.octave
$ octave -qf QR.octave > QR.pasm
$ parrot QR.pasm > QR.pas
$ fpc QR.pas && ./QR > QR.pl
$ perl QR.pl > QR.php
$ php QR.php > QR.pike
$ pike QR.pike > QR.prolog
$ swipl -q -t qr -f QR.prolog > QR.py
$ python QR.py > QR.R
$ R --slave < QR.R > QR.rexx
$ rexx ./QR.rexx > QR2.rb

В результате, итоговый код QR2.rb не отличается от первоначального QR.rb.
Анатолий Ализар @alizar
карма
751,5
рейтинг 81,4
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (120)

  • +89
    вот он, бог ненормального программирования явился нам из цифрового хаоса!
    • НЛО прилетело и опубликовало эту надпись здесь
      • +9
        учитывая закольцованность, можно начать с любого из 50 языков
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Он написал программы а потом с помощью популярной тулзы отформатировал код 2-мерным ASCII артом. Такую «картинку» можно из любого кода сделать — это всего лишь пост-порцессинг :). Оригинальный исходник, думаю, совсем по-другому выглядит.
      • +40
        Так, да не так. Форматирование-то восстанавливается на последнем этапе.
        • +2
          Всё, мозг сломался совсем.
      • 0
        В твиттере он написал, что кто-то другой это нарисовал. В последней строке кода ссылка на оба твиттера — и того, кто код писал и того, кто рисовал, если что.
      • 0
        а какой именно тулзы?
        • +1
          Их кучи. Конкретно данный квайн использует самописный код — см. исходники, там есть скрипт который из вектора делает ASCII арт.
        • 0
          Вы случайно не нашли какую-нибудь такую «популярную» тулзу, поскольку я не смог нагуглить ее с первого подхода, а лезть в исходники пока не хочу. Желательно кроссплатформенную.
  • +2
    на отличненько!
  • +6
    А начиналось все давно и, казалось бы, безобидно.
  • НЛО прилетело и опубликовало эту надпись здесь
  • +17
    Мсье знает толк в квайнах!
    • 0
      Не говорите так, а то в реестр жесткой порнухи запишут :) Им-то что, заблочат, а многие и многие даже весьма подготовленные программисты не смогут полюбоваться, обалдеть, подумать о собственном уровне, задуматься, как бы его подтянуть…
  • +2
    Бог программирования, где записаться в эту религию?
    • +2
      записываться не нужно, Бог программирования у вас в душе ;)
      • +24
        У меня и так мало шампуня осталось, а тут ещё он -_-
  • 0
    Хм!.. А каждый промежуточный исходник оформлен в таком стиле? Или может там комикс зашифрован?
    • +1
      Или змейка вертится?
    • +6
      • +2
        по большей части везде однострочники. попадаются в цепочке экземпляры с метровыми текстами
  • –4
    мысли вслух, а то что прошло через другие языки скомпилируется ли?
    • +3
      Не все языки компилируемые.
  • 0
    Эта его не первая попытка.

    icce.ya.ru/replies.xml?item_no=1048
  • +10
    А теперь цикл статей по подробному разбору всего этого дела бы. :)
    • 0
      Ну, я более-менее разобрал. Скорее менее чем более, но принцип понятен.
  • +9
    Да я о части языков даже и не слышал!
    • –1
      «пока программа на REXX снова не генерирует изначальный код на Ruby.»
      REXX мой любимый язык, для скриптинга, например.
      • –1
        Ну и зря. Минусуете зря. Вот например квайн на рексе, самовоспроизводящий само себя, любого произвольного размера. Это я ещё с извращениями написал. Вся суть в hex-е комментария.
        /* 444F20693D3120746F20736F757263656C696E6528293B53415920736F757263656C696E652869293B454E44 */
        INTERPRET X2C(word(sourceline(1),2))
        /* Дальше можно писать любой код, который выполнится после показа исходников */
        
        • 0
          Это не квайн, квайну нельзя читать файлы. Включая сам файл программы.
          • 0
            Он не читает файлы. В скрипте нет ключевых слов STREAM или LINEIN / CHARIN. Sourceline берёт текст же загруженного в память скрипта.
            • 0
              Вот, только что специально проверил. Вставил между первым комментом и INTERPRET «Call SySleep 15» и ока он там висел на паузе, напечатал в конец всякой лабуды. Всё ок. Лабуда не квайнится.
  • –15
    У меня всего два вопроса: как и на#уя?
    • +3
      Видимо он какой-то принцип уловил.
      • +1
        Очень похоже на то. Тут же все программисты, которых уже не должен так уже сильно удивлять факт, что на любом Тьюринг-полном языке программирования можно сделать реализацию любого другого Тьюринг-полного языка программирования. А тут что-то очень похожее, но мне непонятно, это «более сильное», «более слабое» или «эквивалентное» утверждение, потому что я совсем не математик. А вот автор, похоже, по характеру мышления именно математик, а эту инженерно-художественную работу выполнил как наглядное доказательство некой теоремы.

        Хотя голова от удивления немного кружится, да. Даже не от реализации (я ничего подобного не умею), а именно когда «улавливаешь принцип».
    • +4
      ответить как не смогу,
      а вот «зачем»: он же программист, и поэтому just for fun.
    • +34
      Для повышения собственной квалификации. В какой-то момент времени за драконов экспу перестают давать. И чтобы получить следующий левел приходится выступать на конференциях, разрабатывать собственные языки программирования и такие вот квайны. Полученный левел потом используется для зарабатывания денег традиционным способом — разработкой или руководством разработкой. И код, который пишут такие товарищи в продакшн, обычно очень прост и понятен. Как-раз из-за высокого левела.
  • +1
    японский бог! мой мозг отказывается верить… кто-нибудь знает технологию создания этого?
    • +11
      Конечно знаем. Много свободного времени и блестящий мозг.
    • +1
      Технологию создания квайна или форматирования кода картинкой? Это две совершшенно независимые друг от друга задачи :).
      • +2
        Ну на HQ9 и HQ9+ квайн вообще пишется одним символом :)
        • +1
          да-да, и «Войну и мир» по каналу связи можно передать в виде одного бита. ;)
  • +10
    Идеальный стресс-тест для IDE. Сидишь, переключаешь подсветку синтаксиса для 50 языков по кругу… и оно должно работать =) Выглядел бы этот процесс как новогодняя гирлянда…
    Кстати, да. Кто не посмотрел сорсы этого чуда, потерял 50% смысла статьи.
    • +4
      >Кстати, да. Кто не посмотрел сорсы этого чуда, потерял 50% смысла статьи.
      Только нужно учесть, что обратного выхода нет.
    • +4
      Без подсветки красивее.
  • +24
    Вот оказывается как выглядит программист 80 уровня.
  • 0
    нереально крут
  • +6
    Вот бы еще кто-нибудь разобрался и расписал доступным языком как вообще такое можно сделать.
  • +3
    Мне вот интересно: в сорсах видно, что многие идентификаторы разорваны пробелами, образующими рисунок, значит там где-то зашито удаление этих пробелов?
    • –2
      Если не ошибаюсь, то да. Файл whitespace.rb
      • –4
        whitespace.rb это исходник на языке Whitespace
        • +5
          whitespace.rb — это, очевидно, исходник на языке Ruby, на котором написан интерпретатор языка Whitespace. Об этом автор написал в README в гитхабе.
    • 0
      Там евалы же есть, там, наверное.
  • +3
    по шестиугольнику мы таки догадываемся, кто заказчик!
    • +2
      Только это не шестиугольник, а звезда Давида )
      • +4
        Вообще-то это Гексаграмма и она намного древнее того времени когда Давид её начал на свои щиты рисовать.
        Если так выражаться, то можно заявить что и свастику придумали фашисты.
    • +3
      Мицгола на вас нет! :)
      • +6
        Почему же нет? Вот, пожалуйста.
        • +2
          Оперативно вы.
      • +1
        +100 к скиллу кастования Мицгола!
  • +7
    ✡?!
    • 0
  • 0
    Хорошо когда много свободного времени. Плохо когда нечем его занять.
  • 0
    Реально круто… Или нереально круто… Так сразу и не поймешь…
  • +5
    Изображение в центре — ночной кошмар конспирологов всея Рунета:) автору респект, ждем страшилок о рептилоидах, приступивших к внедрению в земные компьютерные сети сверхчеловеческого ИИ и окончательно ложащих конец на всё исконно-посконное:)
  • +10
    Там ещё и на brainfuck-e шаг. Шикарно.
    • +1
      А чем плохи шаги на Whitespace и Unlambda?
  • 0
    Надо ему подкинуть идею, чтобы каждый из языков(ели есть возможность) делал отдельную версию под основные Оси.
    • 0
      Зачем? Всё кроссплатформенно же.
  • +4
    Японский рубист Юсукэ Эндо (Yusuke Endoh)

    Корректнее:
    Японский рубист Юсукэ Эндо (遠藤 侑介)
    • +1
      «Yusuke Endoh» все-таки выглядит лучше, чем четыре прямоугольника. Не у всех в шрифтах есть иероглифы.
      • +4
        А чем здесь английская транскрипция лучше русской? Какую дополнительную информацию она несёт?
        • 0
          Не лучше русской, но лучше оригинала.
          • +2
            Ок, спрошу по другому: чем пара «русская транскрипция + английская транскрипция» лучше пары «русская транскрипция + оригинал»? Во втором варианте написание на японском несёт дополнительную информацию (хотя и не всем), а вот в первом английская транскрипция просто не несёт никакой дополнительной информации, но отсутствует оригинал, и которого хотя бы некоторые могли получить эту самую дополнительную информацию. Или это позиция «если не мне, то никому»?
            • 0
              Это слишком мелкий вопрос, чтобы по нему «иметь позицию». Просто читаемый текст выглядит лучше.
              • +2
                Просто читаемый текст выглядит лучше.
                Если для вас это важно — поставьте _себе_ юникодный шрифт. А ради _своего_ мелкого удобства навязывать какое-то поведение другим людям и лишать их информации — не очень красиво выглядит.

                И — вопрос-то мелкий, а вот позиция, которую он обнажает, вполне конкретная.
                • +1
                  Использованную транскрипцию нельзя назвать английской. Это так называемое «паспортное ромадзи», используемое в Японии для латинизации имён собственных, и к языку не привязано. А поскольку текст на русском языке, латиница там не нужна, если, действительно, не несёт дополнительной информации.
                  • +1
                    Да, спасибо за уточнение. Прилагательное «английский» здесь действительно не совсем верно.
                • 0
                  А ради _своего_ мелкого удобства навязывать какое-то поведение другим людям и лишать их информации — не очень красиво выглядит.

                  А навязывание вы где, простите, нашли?
                  • +1
                    Ваш комментарий читается так: «у меня (а, может быть, и ещё у кого-то) не отображаются иероглифы, поэтому замените их на латиницу». Выделенное вы в явном виде не писали, но оно отчётливо подразумевается.
                    • 0
                      Как автор того комментария (и, таким образом, единственный, кто точно может знать, что именно подразумевалось) спешу заверить, что ничего подобного не подразумевалось. Ваша же интерпретация… ну что ж, это всего лишь одна из возможных интерпретаций.
            • 0
              Английская транскрипция лучше японской тем, что по ней удобнее делать поиск, т.е. получать дополнительную информацию на языке, который большинство более-менее знает.
  • 0
    А в конце покажут мультик!
    • +11
      Кстати, о мультиках — вот еще псевдоквайн от него же. С анимацией!
      • 0
        Как увидел это, у меня челюсть отпала o_O! Он нереальный гений.
        • 0
          Просто японцы инопланетяне, по моему. Или раньше были роботами, не зря-ж у них так популярны андроиды (человекоподобные, а не телефоны)
      • +1
        После того, как сходил по ссылке, сел в уголок и заплакал.
    • +5
      Мультик уже есть -«Ну Погоди!», 12 выпуск, там где волк кувшин молотком бьет.
  • +1
    Охренеть, не побоюсь этого слова.
    Я вечером поставлю Ubuntu лишь для того, чтобы увидеть процесс компиляции и все промежуточные результаты собственными глазами.
    • 0
      промежуточные результаты habrahabr.ru/post/186782/#comment_6496848
      а если под процессом компиляции вы имели в виду все промежуточные шаги квайнинга, то там все довольно скучно и никакого выхлопа в консоль нет.
  • +3
    Он не просто рубист, но и developer, manager & release manager ветки ruby-trunk
  • +6
    У него ещё есть вращающийся глобус

    image

    после каждой компиляции.
    mamememo.blogspot.no/2010/09/qlobe.html
    • +8
      Всегда было интересно — что творится в голове у таких людей…
  • 0
    на компиляции 17 шага — компьютер был захвачен Слаанеш
  • +3
    Каждый раз, когда я думаю, что японцы уже не смогут удивить меня своим безумием, они вытворяет нечто этакое…
  • 0
    Мне вот интересно, а что на выходе у верилога, это же язык описания железа.
    • +2
      $write("") там одни. В общем не синтезируемая штука, тестбенч своеобразный.
  • +2
    >quine-relay / QR.rb
    > mame 3 hours ago * fix the typo, now

    -Copyriht (c
    +Copyright (c

    Да он троллит! :-)
    • 0
      20-я строка:
      PLEAS EGIVEUP^");end";s=#{E[%(.classXpublicXQR`n.superXjava/la ng/Object`n.me
      «Please give up» можно перевести как «Да ладно, сдавайся».
      Так что ещё как троллит :)
  • +3
    Таким людям памятники надо ставить…

    Код на брейнфаке, кстати, однообразен как-то.
  • +1
    Невероятно!
    Человек явно умеет доводить дело до конца, я бы сдался, респект :)
  • 0
    Красота!
  • +4
    Спасибо, я охренел.

    Нет ли информации, сколько времени он на это потратил?
    • 0
      Думаю, он мог этим заниматься в свое удовольствие, в свободное от работы время, год-два. Но это лишь мое предположение. Вряд ли он круглосуточно сидел и корпел над этой работой.
  • +1
    Осталось добавить в этот «круг ада» malbolge и этому программеру можно ставить памятник :)
    • +1
      Работающий исходный код для песни «99 бутылок пива» с использованием настоящих циклов. Написан Хисаси Идзавой.

      отсюда
      • +1
        Тут уже квайн для него реализован.
        Так что ждем очереди Юсукэ Эндо
  • +2
    Кто-нибудь еще экспериментировал?)

    http://ideone.com/6THB2F

    Чтобы написать квайн, нужно написать квайн. Вот отличная статья на тему квайнов:
    Quines (self-replicating programs )
    А также на хабре: Как писать квайны
    Основной смысл: программный код условно делится на часть данных и часть кода. В процессе выполнения программы код использует данные для вывода исходного текста. При этом в части данных должен содержаться весь исходный текст.
    В квайнах есть место, которое не требует дубликации — интрон. Он-то как раз и позволяет делать маневры.
    • 0
      Извините, а что такое «интрон»? А то Google советует что-то про ДНК. Судя по тому что там написано, если бы я разбирался в ДНК, то смог бы провести аналогию… Но, к сожалению строение ДНК — не мой конёк.
      • 0
        Все верно, термин интрон вводится автором статьи по аналогии с интроном ДНК. Цитата из статьи:
        If we are to take an analogy with cellular biology (thanks to Douglas Hofstadter again), what I have called the “code” would be the cell, and the “data” would be the cell's DNA: the cell is able to create a new cell using the DNA, and this involves, among other things, replicating the DNA itself. So the DNA (the data) contains all the necessary information for the replication, but without the cell (the code), or at least some other code to make the data live, it is a useless, inert, piece of data.
        Note how the data may contain (depending on how it's interpreted) bits that aren't used to write the code, but are still copied when the data is written on the output. Such bits are called introns, in analogy with the parts of the genetic code which aren't used to produce proteins.

        Вольный перевод:
        Если провести аналогию с клеточной биологией (спасибо Дугласу Хофштадтеру снова), то что я назвал «код» будет ячейкой, а «данными» будут клетки ДНК: клетка способна создать новую клетку с помощью ДНК, и это включает, среди прочего, репликацию непосредственно ДНК. Таким образом, ДНК (данные) содержит всю необходимую информацию для репликации, но без клетки (кода), или по крайней мере какого-либо другого кода, делающего данные «живыми», это бесполезная, инертная, часть данных.
        Обратите внимание, что данные могут содержать (в зависимости от того, как они интерпретируются) биты, которые не используются для написания кода, но все равно повторяются, когда данные записываются на выходе. Такие биты называются интронами, по аналогии с частями генетического кода, которые не используются для производства белков.

        Ну и если взглянуть на код из моего поста выше, в нем интрон расположен в строках с 9 по 14, а код использует индексы для чтения массива данных, не затрагивая интрон при выводе самого себя.
        В общем интересная статья, всем заинтересованным в квайнах можно рекомендовать для прочтения.
  • 0
    Мой скромненький квайн, который я придумал и написал лет пять назад, а до этого на Си лет 10 назад по тому же принципу.
    <?php   
        function hexToStr($hex)  
        {  
            $string='';  
            for ($i=0; $i < strlen($hex)-1; $i+=2)  
            {  
                $string .= chr(hexdec($hex[$i].$hex[$i+1]));  
            }  
            return $string;  
        }  
        $param = "|3c3f706870200d0a2020202066756e6374696f6e20686578546f5374722824686578290d0a202020207b0d0a202020202020202024737472696e673d27273b0d0a2020202020202020666f72202824693d303b202469203c207374726c656e2824686578292d313b2024692b3d32290d0a20202020202020207b0d0a20202020202020202020202024737472696e67202e3d206368722868657864656328246865785b24695d2e246865785b24692b315d29293b0d0a20202020202020207d0d0a202020202020202072657475726e2024737472696e673b0d0a202020207d0d0a2020202024706172616d203d20227c223b0d0a20202020246465636f646564203d20686578546f537472287375627374722824706172616d2c3129293b0d0a20202020666f72202824693d303b202469203c207374726c656e28246465636f646564293b202b2b2469290d0a202020207b0d0a096966286f726428246465636f6465645b24695d293d3d313234297b0d0a2020202020202020202020206563686f2024706172616d3b0d0a20202020202020207d656c73657b0d0a2020202020202020202020206563686f20246465636f6465645b24695d3b0d0a20202020202020207d0d0a202020207d0d0a3f3e";  
        $decoded = hexToStr(substr($param,1));  
        for ($i=0; $i < strlen($decoded); ++$i)  
        {  
        if(ord($decoded[$i])==124){  
                echo $param;  
            }else{  
                echo $decoded[$i];  
            }  
        }  
    ?>  
    


    Но он не настолько крут :)
  • 0
    Куски вроде «invokevirtualXjava/i o/PrintStream/Hln(Ljava/lang/SJ;)V» настораживают — байткод прямо в сорцах? Обратная совместимость может пострадать.
  • НЛО прилетело и опубликовало эту надпись здесь

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.