программа которая выводит свой код

Куайны (бесполезная программа в программе)

Авторизуйтесь

Куайны (бесполезная программа в программе)

Куайн (от анг. quine) — программа, результатом работы которой является собственный исходный код. Сразу оговоримся: программы, которые обращаются к файлам или производят считывание с клавиатуры куайнами не являются. Более серьезное ограничение: программы, которые могут напрямую получить доступ к своему исходному коду (средствами языка), также не являются куайнами.

А существуют ли они?

Несмотря на простую формулировку задания, потратив немного времени на ее решение, возникает вопрос: существуют ли вообще такие программы? Ответ: Да!

Более того, куайн существует в любом языке, способном выводить произвольную вычисляемую строку! Впервые эта идея была описана Полом Братли и Жаном Милло. А первым куайном считается программа, написанная на языке Atlas Autocode Хэмишем Дюаром.

А на современных языках?

JavaScript:

Pascal:

Итак. Мы убедились, что такие программы существуют, а теперь немного теории о том, как их сделать.

Грабли

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

Чтобы исправить положение, вообще не будем вносить в переменную сам факт присваивания. То есть:

После, во время вывода подставим значение с в её же определение.
Хорошо, но возникает проблема с кавычками. Языки, в которых определены одинарные и двойные кавычки, справляются с проблемой хорошо (мы говорим о том, что можно создать переменную q=» ‘ «, а потом вывести ее значение в ее определение), но что делать, например, с языком С? Экранирование, очевидно, не поможет, так как его тоже надо экранировать… В этом случае, можно задать кавычки кодом символа и вывести его.

Теперь остается проблема вставки строки в выходную строку с. Здесь вспомним про printf и всю его мощь.

Чаще всего методы взятия подстроки умеют брать её до конца:

Практика

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

Python

Высший пилотаж

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

Такого рода программы называются цепные куайны, и на сегодняшний день, самый большой цепной куайн (длина цепи уже достигла 100 языков) написан японцем Юсукэ Эндо.

Для того, чтобы работало:

Ну и, соответственно, результат каждой программы нужно запускать самим:

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

Ах да, языки программирования в куайне расположены в алфавитном порядке.

Источник

Как писать квайны

Введение

Многие программисты считают написание квайнов (программ, выводящих свой исходный код) непосильной задачей. И действительно — все эти цепные квайны и квайны различного порядка, при взгляде на которые можно потеряться в, казалось бы, бессмысленном наборе символов…

Читайте также:  коды ошибок уаз патриот 409 двигатель

Однако, на самом деле, написать квайн на каком-либо языке не так сложно, как кажется. Сейчас я расскажу, как сделать это на различных языках программирования. Более того, мы не будем использовать «хаки» интерпретеруемых языков вроде операции вывода исходного кода и функций типа eval и напишем квайны на интерпретируемых и компилируемых языках.

Теория

Попробуем написать квайн. Для этого возьмём инструкцию языка для вывода и передадим ей как параметр код программы. Однако, в коде мы снова используем этот же код и так далее — возникает бесконечная рекурсия. Но что можно сделать для того, чтобы не передавать строковую константу? Решение — поместить строку (копию части кода) в переменную. Для удобства назовём такую строку s-строкой, а переменную с этой строкой — s-переменной. Чтобы и в s-переменной не было рекурсии, мы просто исключим из неё фрагмент со значением этой самой переменной. То есть, выглядеть это будет примерно так:

C:
Примечание. Как в этом фрагменте, так и в квайнах, которые получатся в итоге, для простоты мы не будем соблюдать правила форматирования кода. Тем не менее, их соблюдение вы сможете без труда добавить самостоятельно после прочтения статьи.

Далее, при выводе, мы подставим значение s-строки в её же определение в коде (в примере выше — перед тремя последними символами). Здесь же возникает ещё несколько проблем. Первая проблема — при подставлении в s-строке нельзя использовать символы, которые поведут себя в коде не так, как надо. Например, мы не можем так просто вставить кавычку — ведь вместо того, чтобы стать частью s-строки, она завершит её определение и выводимый код не будет совпадать с исходным, являясь некорректным вообще.

Экранирование применить здесь достаточно сложно — символ экранирования надо тоже экранировать и т.д.. Гораздо проще, например, использовать другой вариант кавычек — так, во многих интерпретируемых языках разрешено использование как одинарных, так и двойных кавычек для задания строки, а отличие состоит в том, что можно без проблем использовать одну кавычку в константе, если она ограничивается другими. То есть, код ‘»‘ создаст односимвольную строку с двойной кавычкой, а код «‘» — с одиночной. Если использовать этот вариант, удобно задать в начале переменную с какой-либо кавычкой, а затем использовать её при выводе.

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

Следующая проблема — вставка другой строки (или символа с каким-либо кодом) в вывод s-строки. Решение здесь очевидно — брать подстроку s-строки специальной функцией, выводить её, далее выводить то, что надо вставить, затем выводить другую подстроку s-строки. Может показаться, что в Си взятие подстроки для вывода потребует немало кода. Тут нам на помощь придёт мощь функции printf. Так, например, вот варианты кода для различных языков, печатающего часть строки s со второго символа (считая с единицы) по четвёртый включительно:

Python:
Ruby:
Perl:
C:
Обычно методы взятия подстроки могут также брать её остаток до конца. Например, напечатаем строку s со второго символа до конца строки (то есть, всю строку кроме первого символа):

Читайте также:  коды на гт5 икс бокс 360

Python:
Ruby:
Perl:
C:
Если такой возможности нет, придётся на место параметра с длиной подстроки поставить заглушку типа «XX», а затем в конце посчитать символы до конца и подставить их вместо «XX» в коде и в s-строке, не изменяя длины различных частей кода. Например, если в длине окажется одна цифра, целесообразно подставить вместо первого икса пробел, ведь, если его удалить, длины частей s-строки изменятся и их придётся пересчитывать.

Интерпретируемые языки

Итак, начнём писать квайны, собрав все суждения выше. На Python я написал такой квайн (работает и на 3.x):

Здесь переменная q используется как переменная, где хранится одинарная кавычка, далее идёт определение s-переменной со всем кодом, кроме самой s-строки. После этого идёт вывод s-переменной со следующими вставками:
1). Одинарная кавычка как значение переменной q;
2). Одинарная кавычка как начало определения s-строки;
3). Сама s-строка (да-да, s-строка вставляется внутри s-строки);
4). Одинарная кавычка как конец определения s-строки.

Примечание. При написании квайнов по данному методу не забывайте копировать все изменения в коде в копию кода в s-строке.

С минимальными изменениями можно получить квайн только для Python 2.x:

Абсолютно аналогичны и квайны на других языках, где мы изменяем лишь некоторые синтаксические особенности:

Источник

Вывод на экран программой собственного исходника

23150

Всем, наверное, известна такая вот задачка:

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

P.S. Варианты типа: «Прочитать исходный код из файла и вывести на экран» не решают поставленную задачу.
Т.е., по идее, исходник после компиляции должен содержаться в бинарике.

30 ответов

21800

23150

23929

23150

21800

Да я понял, что исходник надо вывести. Я имел в виду, что дизассемблированием однозначный сорс не получить.

14801

23150

Вот, что у меня получается:

#define D(x) char*t=#x;x
D(\
int main(int c,char**v)\
<\
printf(«#include \n#include \n#define D(x) char*t=#x;x\nD(%s)\n»,t);\
getch();\
>\
)

4073

23150

Дело в том, что твой вариант дублирует в printf(..); весь исходный код программы и просто перепечатывает его 2 раза.
Фактически приходится писать 2-е копии программы.

#define D(x) char*t=#x;x
D(
int main(int c,char**v)
<
printf(«My Source:\n\n#include \n#include \n#define D(x) char*t=#x;x\nD(%s)\n\nEnd of my Source!\n»,t);
printf(«Этот текст тоже будет напечатан. \n»);
printf(«И этот тоже 🙂 \n»);
getch();
>
)

мне кажется более удачным и решает поставленную задачу полностью.
Я думаю вряд ли найдется более удачное решение. 😉

23929

2801

Ну, да ладно. Позвольте, так сказать, внести лепту 🙂
Код, само собой, для Windows.

#include
#include
using namespace std;

#define IDR_SOURCE1 101

int main(int argc, char** argv)
<
char* mysource = (char* )LoadResource( NULL, FindResource( NULL, MAKEINTRESOURCE(IDR_SOURCE1), «SOURCE» ) );
cout

1050

2801

23150

Народ!
Вот вам расширенное решение для тех, кто не верит,
что эта прога не может себя напечатать полностью и (или)
может делать что-то полезное,
не использует внешние ресурсы и т.д. и т.п.

Так вот эта прога может все!:)

P.S. не верите. скомпилируйте.

#include
#include
#include

#define D(x) char*t=#x;x
D(
using namespace std;

int sum(int i)
<
int another_variable;
printf(«Enter integer value. \n»);
printf(«another_variable = «);
cin >> another_variable;
printf(«\tanother_variable = %d\n», another_variable);
return i + another_variable;;
>
int main(int c,char**v)
<
int some_variable = 100;
int selection;
printf(«This prigram can write own source code.\n»);

Читайте также:  намакли раскопки баг с лестницей

Источник

Квайны

Определение:
Квайном (англ. quine) [1] называется программа, которая выводит свой исходный код. При этом программа не должна использовать внешние данные (например, читать файл со своим исходным кодом).

Стоит отметить, что программы, использующие для чтения своего кода файловую систему, квайнами не считаются. Например, программа на BASIC вида

выводит на экран свой исходный код, поскольку команда [math]\mathtt[/math] просит среду исполнения вывести в консоль текущую программу (эта функция была необходима для программистов, так как код программы зачастую не мог поместиться на консоль 80×25 символов).

Квайн состоит из двух сегментов: кода и данных. Данные представляют собой текстовую версию кода, и, как правило, получаются из кода простым добавлением обрамляющих кавычек. Код, в свою очередь, сначала использует данные, чтобы вывести код, содержащийся в них, а затем просто выводит данные.

Формально общий принцип написания квайнов содержится в доказательстве теоремы о рекурсии. Далее будет рассмотрено понятие мультиквайна.

Содержание

Мультиквайны [ править ]

Связанные определения [ править ]

Определение:
Интроном (англ. intron) [2] называется часть сегмента данных, которая не используется для вывода кода, но сохраняется в процессе саморепликации квайна.

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

Докажем утверждение для биквайна. Для большего количества языков доказательство будет выглядеть аналогично.

Принцип написания [ править ]

Будем следовать доказательству и напишем мультиквайн для двух языков. Далее покажем, как добавить новый язык.

Вторая программа может быть получена запуском первой с нужным аргументом.

Теперь добавим третий язык:

Две оставшиеся программы будут выглядеть аналогично и смогут быть получены путём запуска третьей с каждым из возможных аргументов.

Источник

Quine на Python

Программисты тоже умеют развлекаться, так что давайте сегодня развлечемся и напишем quine (квайн). Квайн – это такая программа, которая выводит на экран свой же код, ни больше, ни меньше. Сразу договоримся, что пустая программа на Python, которая ничего не выводит, не считается квайном; это не интересно.

В Python у нас есть чудо-переменная, которая хранит путь к текущему интерпретируемому файлу, поэтому можно сделать так:

Нам нужно что-то печатать, значит берем print:

Программа начинается с print…, значит и печатать будем тоже самое:

Не получается, потому что у нас тут уже два print да кавычки, а печатается только один. Так можно плодить print до бесконечности, но все равно не будет хватать одного в выводе. Будем решать поэтапно. Давайте заведем переменную s с кодом нашей программы.

Но код теперь начинается с s=, исправим:

Смотрите, уже похоже, осталось только на место знака вопроса воткнуть содержимое строки s из оригинального кода. Это самый важный момент. Используем format, а точнее s.format(s), который в определенном месте строки s вставит саму же строку s, таким образом, мы «разрываем рекурсию»:

Отлично! Но тут два недостатка: во-первых, не забыть добавить s.format(s) в саму строку s:

Ура! Квайн готов и работает!

🐉 Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈

Источник

Поделиться с друзьями
admin
Здоровый образ жизни: советы и рекомендации
Adblock
detector
Теорема (о существовании мультиквайнов):