Очень краткое введение в quines и реле quines

Преамбула

Эта статья предназначена только для того, чтобы наивно представить quines как концепцию, это просто рассказ о TIL (Today I Learned), посвященный интересной части компьютерных наук, о которой я не знал в прошлом. Для получения более подробных докладов и статей о квинах и их работе я рекомендую ознакомиться со ссылками в конце этой статьи.

Краткое введение

Quine — это компьютерный термин, который описывает:

❝ ㅤ Компьютерная программа, которая не принимает никаких входных данных и создает копию собственного исходного кода в качестве единственного вывода

Проще говоря, Quine — это фрагмент кода, который распечатывается при выполнении.

Термин «Куайн», названный в честь математика Уилларда ван Ормана Куайна, впервые появился в книге ученого-когнитивиста Дугласа Хофштадтера под названием «Гедель, Эшер, Бах» в 1979 году. В книге исследуются темы математики, рекурсии, фракталов и многого другого. более.

Делаем куайн

Куайн начинается с двух простых правил:

  • Программа при компиляции и выполнении должна выводить собственный исходный код.
  • Код программы не может просто использовать инструкции ввода-вывода для чтения собственного файла исходного кода с диска.

Некоторым это может показаться невозможным, а другим тривиальным, но, как вы вскоре увидите, создание quine, хотя и возможно на многих разных языках, может оказаться более сложной задачей, чем вы могли изначально подумать.

Первый наивный подход к проблеме

Начнем с создания простой программы на C++.

Теперь давайте начнем печатать исходный код программы изнутри.

Пока довольно легко, верно? Но здесь мы сталкиваемся с проблемой, следуя нашей текущей логике, теперь нам нужно принять во внимание недавно добавленные инструкции вывода, поскольку теперь они являются частью исходного кода, который нам нужно вернуть.

Бьюсь об заклад, вы можете видеть проблему здесь, это в конечном итоге приводит к бесконечному циклу и таким образом не может функционировать как квайн.

Функциональные примеры

Теперь, когда мы знаем, что quines довольно сложно реализовать, давайте быстро рассмотрим несколько функциональных примеров:

Приведенный выше пример представляет собой Quine, созданный на Python, совместимый с Python 2.x и Python 3.x.

Такого результата можно добиться благодаря интерполяции строк с оператором %r. Преобразование формата %r использует функцию repr() для возврата строки, содержащей представление исходного кода ее аргумента.

Большинство языков могут создавать от одного до нескольких квинов. Выше приведен однострочный пример, использующий преимущества добавления оператора walrus в Python 3.8 наряду с простой реализацией exec и f-строки.

Дополнительные интересные примеры на разных языках (включая C++, HTML, CSS и даже Brainf****) см. в этом тщательно отобранном списке: http://rosettacode.org/wiki/Quine

Реле Куайна

Теперь, когда мы кратко представили квины, давайте рассмотрим еще один интересный пример.

Как вы теперь знаете, квайн — это фрагмент кода, который выводит сам себя. Но что, если вместо того, чтобы напрямую выводить себя, как в приведенных выше примерах, наш фрагмент будет выводить другой другой фрагмент кода, который при выполнении вернет наш исходный фрагмент, ну, это именно то, что представляет собой ретранслятор quine. Вы можете виртуально добавить столько шагов, сколько пожелаете, в ретрансляторе quine, пока он в конечном итоге не вернется к исходному фрагменту кода.

Один пользователь github по имени mame довел этот принцип до крайности. В его ретрансляторе quine есть программа Ruby, которая генерирует программу Rust, которая генерирует программу Scala, ретранслируя через 128 языков, пока не достигнет программы REXX, которая снова генерирует исходный код Ruby. https://github.com/mame/quine-relay