Домой

Программа которая печатает саму себя


Программа, которая печатает саму себя. Называется "Куайн" (quine). Определение на Википедии тут. Не в смысле просто выдает на печать файл со своим текстом - это было бы слишком просто, программа выводит на консоль свой текст "из самой себя". Не самая простая штука, небольшая разминка для серых клеточек. Впрочем, гениальной её тоже не назовешь - обдумана и сделана за пол часа. (Тут просьба для гениев - перестать громко смеяться.)

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

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

Правда есть еще одна маленькая проблемка - это ограничители строки. Нужна некая подстановка символов - ограничителей литералов, что-бы не войти в рекурсию при ограничении строковых констант, к счастью, в моём любимом Дельфи есть общий метод представления строковых литералов - это его прямой ASCII-код с префиксом #.

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

program selfprint;

{$APPTYPE CONSOLE}

const
  z = 19;
  p = #32#32#32#32#39;
  m : array[1..z] of string = (
    'program selfprint;',
    '',
    '{$APPTYPE CONSOLE}',
    '',
    'const',
    '  z = 19;',
    '  p = #32#32#32#32#39;',
    '  m : array[1..z] of string = (',
    '  );',
    '',
    'var',
    '  i: integer;',
    '',
    'begin',
    '  for i := 1 to 8 do writeln(m[i]);',
    '  for i := 1 to z-1 do writeln(p+m[i]+#39#44);',
    '  for i := z to z do writeln(p+m[i]+#39);',
    '  for i := 9 to z do writeln(m[i]);',
    'end.'
  );

var
  i: integer;

begin
  for i := 1 to 8 do writeln(m[i]);
  for i := 1 to z-1 do writeln(p+m[i]+#39#44);
  for i := z to z do writeln(p+m[i]+#39);
  for i := 9 to z do writeln(m[i]);
end.
            


Вот тут скачивается архив с исходниками и скомпилированной программой.


Еремеев Алексей