Программа, которая печатает программы

13

Вызов

Ваша цель - написать программу, которая печатает другую программу. Эта напечатанная программа должна напечатать другую программу, а новая программа должна напечатать другую программу до конца.

правила

  1. Каждая программа должна содержать не более 256 байт. (Если это необходимо изменить, оставьте комментарий)
  2. Последняя программа должна быть пустой программой.
  3. Должно быть конечное количество программ, поэтому программа не может быть квинной.
  4. Все программы должны работать на одном языке.
  5. Вход не разрешен.
  6. Программа-победитель - это программа, которая печатает столько программ, сколько возможно, считая себя.

Удачи!

Черепаха
источник
Максимальный балл - 2^2048или 3.2317e616.
orlp
Чтобы упростить сравнение больших баллов, пожалуйста, включите приблизительное значение к вашему баллу в форме, a*10^bгде 1<=a<10и bявляется натуральным числом.
Flawr
2
На самом деле мой предыдущий расчет был неверным. Предполагая, что программа должна быть в байтах, максимально возможная оценка <число слишком длинное для комментария> или 1.2673e614.
orlp

Ответы:

20

CJam, 4,56 × 10 526 программ

2D#2b{"\256b_(256b:c'\s`_:(er`":T~{;38'ÿ*`{:T~{;63'ÿ*`{:T~{;88'ÿ*`{:T~{;114'ÿ*`{:T~{;140'ÿ*`{:T~{;166'ÿ*`{:T~{;192'ÿ*`{:T~{;219'ÿ*`{Q?\"_~"}s(\T}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}_~

Точный счет: 254 219 + 254 192 + 254 166 + 254 140 + 254 114 + 254 88 + 254 63 + 254 38 + 254 13 + 3

Все программы должны быть сохранены с использованием кодировки ISO-8859-1, чтобы соответствовать ограничению размера файла.

Спасибо @ChrisDrost, который указал на ошибку и предложил подход к вложению .

Попробуйте онлайн в интерпретаторе CJam .

254 219 + 2 ≈ 4,56 × 10 526 программ

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

"ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ"
{\256b_(256b:c'\s`_:(er`Q?\"_~"}_~

Запуск этой программы производит программу

"ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ"
{\256b_(256b:c'\s`_:(er`Q?\"_~"}_~

и после 254 219 - еще 1 итераций, программа

{\256b_(256b:c'\s`_:(er`Q?\"_~"}_~

Последняя непустая программа завершается с ошибкой 2 и ничего не печатает (пустая программа).

Как это устроено

Предположим, что строка уже находится в стеке.

{      e# Push a code block.
  \    e# Swap the string on top of the code block.
       e# This will cause a runtime error if there is no string on the stack.
  256b e# Convert the string (treated as a base-256 number) to integer (I).
  _(   e# Copy the integer and decrement the copy.
  256b e# Convert the integer into the array of its base-256 digits.
  :c   e# Cast each base-256 digit to character. Converts from array to string.
  '\s  e# Push a string that contains a single backslash.
  `    e# Push its string representation, i.e., the array ['" '\ '\ '"].
  _:(  e# Push a copy and decrement each character. Pushes ['! '[ '[ '!].
  er   e# Perform transliteration to replace "s with !s and \s with [s.
       e# This skips characters that require escaping.
  `    e# Push its string representation, i.e., surround it with double quotes.
  Q    e# Push an empty string.
  ?    e# Select the first string if I is non-zero, the empty string otherwise.
  \    e# Swap the selected string with the code block.
  "_~" e# Push that string on the stack.
}      e#
_~     e# Push a copy of the code block and execute it.
       e# The stack now contains the modified string, the original code block
       e# and the string "_~", producing an almost exact copy of the source.

254 192 ≈ 5.35 × 10 461 больше программ

Здесь все становится немного сумасшедшим.

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

Программа

"ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ"
{"\256b_(256b:c'\s`_:(er`":T~{;219'ÿ*`{Q?\"_~"}s(\T}?\"_~"}_~

аналогична первой программе предыдущего раздела, и запуск первого и его вывод за 254 192 итерации приводит к последнему.

Предположим, что строка уже находится в стеке:

{                           e# Push a code block.
  "\256b_(256b:c'\s`_:(er`" e# Push that string on the stack.
                            e# The characters inside it behave exactly as
                            e# they did in the previous section.
  :T~                       e# Save the string in T and evaluate it.
  {                         e# If the integer I is non-zero, keep the generated
                            e# string; else:
    ;                       e#   Pop the code block from the stack.
    219'ÿ*`                 e#   Push a string of 219 ÿ's (with double quotes).
    {Q?\"_~"}               e#   Push that block on the stack.
    s                       e#   Push its string representation.
    (\                      e#   Shift out the { and swap it with the tail.
    T                       e#   Push T.
  }?                        e#
  \                         e# Swap the selected string with the code block
                            e# or T with the tail of the code block.
  "_~"                      e# Push that string on the stack.
}                           e#
_~                          e# Push a copy of the code block and execute it.

Моар программы

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

Повторяя эту технику снова и снова, пока мы не достигнем предела 255 байт, мы можем добавить в общей сложности 254 166 + 254 140 + 254 114 + 254 88 + 254 63 + 254 38 + 254 13 + 1 ≈ 1,59 × 10 399 программ те из предыдущих разделов.


1 Новая строка добавлена ​​для ясности.
2 По согласованию на Meta , это разрешено по умолчанию.
3 или 0,0000000000000000000000000000000000000000000000000000000000000000000000000012%

Деннис
источник
5

JavaScript, 1000 программ

x=999;
q=";alert(x=999?`q=${JSON.stringify(q)+q}`.split(x).join(x-1):``)";
alert(
    x ? `x=999;q=${JSON.stringify(q)+q}`.split(x).join(x-1) // basically .replaceAll(x, x-1)
      : ``
)

Справедливо ли это, зависит от того, как именно понять третье правило.

Ypnypn
источник
Это не технически Куайн, так как он печатает модифицированную версию своего собственного исходного кода , а не идентичную копию. Очевидно, он использует квиноподобные методы. Я думаю, нам понадобится разъяснение от @TheTurtle.
JohnE
5
@JohnE и Ypnypn Это то, что я предполагал. Это работает.
Черепаха
6
Вы все еще значительно ниже предела длины кода. Почему бы вам не изменить 999 на что-то большее?
DankMemes
4

Ruby, 1.628 × 10 ^ 237 программ

a=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;_="a=%#x-1;_=%p;puts _%%[a,_]if a";puts _%[a,_]if a

Тот же подход, что и в моем Perl-ответе, но поскольку Ruby уже обрабатывает большие целые числа, его проще хранить в виде шестнадцатеричного кода.


Ruby, 9,277 × 10 ^ 90 программ

a=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;b=0xf;(b<1)&&(a-=1)&&b=eval('0x'+'f'*(74-("%x"%a).length));_="a=%#x;b=%#x;(b<1)&&(a-=1)&&b=eval('0x'+'f'*(74-('%%x'%%a).length));_=%p;puts _%%[a,b-1,_]if a";puts _%[a,b-1,_]if a

Так что эта попытка немного отличается от предыдущей квиноподобной, но из-за всех дополнительных функций я не получаю число, столь же близкое к предыдущему ... Хотя было интересно попробовать другой подход!

Дом Гастингс
источник
4

Программы на Python 2, 9.7 * 10 ^ 229

O=0
if len(hex(O))<191:print"O=0x%x"%(O+1)+open(__file__).read()[-68:]
синий
источник
Хорошо, не думал о повторении строки!
Дом Гастингс
2

C, 2,2 * 10 ^ 177 программ

#define S(s)char*q=#s,n[]="#####################################################################################################";i;s
S(main(){while(n[i]==91)n[i++]=35;i==101?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})

Это не идеально, но довольно хорошо. Я имею в виду, что он ровно в 255байтах и ​​генерирует программы одинаковой длины. Вы могли бы, вероятно, еще немного поиграть, чтобы получить еще несколько программ, но я оставлю все как есть.

Программа основана на простой C-квине. Кроме того, существует довольно простой алгоритм подсчета, который рассчитывает все возможные значения массива charn . У нас столько программ, сколько перестановок строки n.

Диапазон символов ограничен диапазоном от #(= 35) до[ = (91). Это потому, что я не хочу ничего "или \в строке, потому что они должны быть экранированы.

Генерация программы заканчивается, когда все значения в массиве char nравны [. Затем он выводит простую фиктивную программу main(){}, которая сама ничего не выводит.

#define  S(s) char *q = #s; /* have the source as a string */ \
char n[] = "#####################################################################################################"; \ 
int i; \
s /* the source itself */
S(main() {
    while(n[i]=='[') /* clear out highest value, so next array element be incremented */
        n[i++]='#'; 
    i==101 /* end of array reached? output dummy program */
        ? q = "main(){}"
        : n[i]++; /* count one up in the whole array */
    printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)", n, q);
})

В качестве демонстрации того, что это должно работать, я просто изменил пределы, поэтому только символы между ASCII-кодом 35 и 36используются , и только 4 элементов массива.

В результате программы

% echo > delim; find -iname 'program_*.c' | xargs -n1 cat delim

#define S(s)char*q=#s,n[]="####";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$###";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="#$##";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$$##";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="##$#";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$#$#";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="#$$#";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$$$#";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="###$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$##$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="#$#$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$$#$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="##$$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$#$$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="#$$$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$$$$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="####";i;s
S(main(){})

Это выводы 2^4 + 1 = 17 разные программы.

Таким образом, вышеприведенная программа выводит ((91-35)+1)^101 + 1 = 57^101 + 1 ~= 2.2 * 10^177разные программы. Я не совсем уверен, если это имеет значение, или если мой расчет даже правильный

MarcDefiant
источник
1
Не могли бы вы указать, что речь идет о 2.2 * 10^177(для тех, кто хочет сравнить)?
Flawr
Не знал, как рассчитать этот, но я включил его ;-)
MarcDefiant
wolframalpha.com =)
flawr
1

Perl, 1 × 10 ^ 163

В противном случае это довольно простая квинна, сокращенная до минимально возможного числа символов, которая работает только тогда, когда счетчик не работает 0.

use bigint;$i=9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999||die;$_=<<'e';eval
print"use bigint;\$i=$i-1||die;\$_=<<'e';eval
${_}e
"
e
Дом Гастингс
источник
1

Common Lisp, 10 113 -1

(LET ((X
       99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999))
  (WHEN #1=(PLUSP X)
    #2=(SETF *PRINT-CIRCLE* T)
    #3=(PRINT (LIST 'LET `((X ,(1- X))) (LIST 'WHEN '#1# '#2# '#3#)))))
  • Есть 113 девяток.
  • Следующая программа имеет 112 девяток, за которыми следуют 8
  • Следующая программа имеет 112 девяток, за которыми следует 7
  • ...

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

CoreDump
источник
1

Perl, 1,4 * 10 ^ 225

use bignum;open$F,__FILE__;$_=<$F>;s/0x\w+/($&-1)->as_hex/e;0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&&print

Аналогичный подход к питону; тот же результат!

александр-Brett
источник
0

> <> , 65534 (?) Программы

Я добавил знак вопроса рядом с 65533, так как мне еще предстоит проверить, что он может печатать 65533 (хотя у меня есть основания полагать, что это должно). Как только у меня будет немного больше времени, я собираюсь найти способ проверить это.

":?!;1-r00gol?!;a0.�

Вы можете попробовать это онлайн здесь .

Суть этой программы в том, что она изменяет вывод символа в самом конце, а затем уменьшает его числовое значение перед печатью. Я получил 65534 программы, потому что значение ascii символа в конце кода равно 65533, поэтому, считая первую программу, мы имеем 65534 (если вы считаете пустую программу 65535, я думаю). Последняя программа «вернулась» - ничто; оно просто заканчивается, когда значение символа равно 0.

Я вполне уверен, что он сможет печатать символ для всех итераций: я не смог найти точный источник для того, сколько символов> <> может печатать, но есть символы непосредственно ниже 65533, численно.

Дайте мне знать, если есть какие-либо проблемы с этой реализацией; Я немного не уверен в правильности моей записи.


объяснение

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

":?!;1-r00gol?!;a0.�
"                     begins string parsing
 :?!;                 terminates program if final character is 0, numerically
     1-               decrements final character by 1
       r              reverses stack
        00g           grabs quotation mark (fancy way of putting " ")
           ol?!;      prints and terminates if stack is empty
                a0.   jumps back to o to loop 

То, что он делает, это анализирует все после кавычки как символы, а затем уменьшает последний. Оттуда он просто переворачивает стопку (чтобы печатать в правильном порядке), помещает кавычку в стопку и затем печатает, пока стопка не станет пустой.

капуста
источник
0

Python, 1 × 10 ^ 194 программ

n=99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
if n:print open(__file__).read().replace(str(n),str(n-1))

Это должно быть запущено из файла, а не из интерактивного репла. Это не Куайн.

Спасибо @The Turtle за помощь в экономии 3 байтов, что больше места для девяток!
Спасибо @poke за помощь в экономии 2 байтов, что больше места для девяток!

Любитель сыра
источник
@ Любитель сыра Это if n!=0избыточно. Вы можете просто написать if n.
Черепаха
Вы также можете избавиться от двух пробелов; после if n:и между replaceаргументами.
тыкай
0

Баш, 52 программы

Совершенно скучный, и (надеюсь) твердо на последнем месте.

echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo
Крис
источник