Program yang Mencetak Program

13

Tantangan

Tujuan Anda adalah menulis program yang mencetak program lain. Program yang dicetak harus mencetak program lain, dan program yang baru harus mencetak program lain, sampai akhir.

Aturan

  1. Setiap program harus kurang dari 256 byte. (Jika ini perlu diubah, tinggalkan komentar)
  2. Program terakhir harus berupa program kosong.
  3. Harus ada sejumlah program yang terbatas, sehingga program tersebut tidak dapat berupa quine.
  4. Semua program harus dijalankan dalam bahasa yang sama.
  5. Tidak ada input yang diizinkan.
  6. Program yang menang adalah program yang mencetak sebanyak mungkin program, menghitung sendiri.

Semoga berhasil!

Kura-kura
sumber
Skor maksimum adalah 2^2048, atau 3.2317e616.
orlp
Untuk memudahkan membandingkan skor besar, harap sertakan perkiraan untuk skor Anda dalam bentuk di a*10^bmana 1<=a<10dan bmerupakan bilangan alami.
flawr
2
Sebenarnya, perhitungan saya sebelumnya salah. Dengan asumsi program harus dalam byte, skor maksimum yang mungkin adalah <angka terlalu panjang untuk dikomentari> atau 1.2673e614.
orlp

Jawaban:

20

CJam, 4,56 × 10 526 program

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`}?\"_~"}_~

Skor pasti: 254 219 + 254 192 + 254 166 + 254 140 + 254 114 + 254 88 + 254 63 + 254 38 + 254 13 + 3

Semua program harus disimpan menggunakan pengkodean ISO-8859-1 untuk memenuhi batas ukuran file.

Terima kasih kepada @ChrisDrost yang menunjukkan bug dan menyarankan pendekatan bersarang.

Cobalah online di penerjemah CJam .

254 219 + 2 ≈ 4,56 × 10 526 program

Pembagian garis skor dapat dicapai dengan program berikut yang jauh lebih sederhana 1 .

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

Menjalankan program ini menghasilkan program

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

dan setelah 254 219 - 1 iterasi lagi, program

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

Program non-kosong terakhir ini keluar dengan kesalahan 2 dan tidak mencetak apa pun (program kosong).

Bagaimana itu bekerja

Asumsikan string sudah ada di tumpukan.

{      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 lebih banyak program

Di sinilah segalanya menjadi sedikit gila.

Program pertama sangat kompresif. Dengan menulis program serupa yang, alih-alih program kosong, akhirnya menghasilkan program pertama dari bagian di atas, kita dapat meningkatkan skor dengan 254 192 program 3 .

Program

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

mirip dengan program pertama dari bagian sebelumnya, dan menjalankan yang pertama dan hasilnya untuk 254 192 iterasi menghasilkan yang terakhir.

Asumsikan string sudah ada di tumpukan:

{                           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.

Program Moar

Program pertama dari bagian sebelumnya masih sangat dapat dikompres, sehingga kita dapat menerapkan metode yang sama dan menulis sebuah program yang, setelah 254 166 iterasi, menghasilkan program yang disebutkan di atas.

Mengulangi teknik ini berulang-ulang sampai kita mencapai batas 255 byte, kita dapat menambahkan total 254 166 + 254 140 + 254 114 + 254 88 + 254 63 + 254 38 + 254 13 + 1 ≈ 1,59 × 10 399 program ke orang-orang dari bagian sebelumnya.


1 Newline ditambahkan untuk kejelasan.
2 Per konsensus di Meta , ini diizinkan secara default.
3 atau 0,00000000000000000000000000000000000000000000000000000000000000000012%

Dennis
sumber
5

JavaScript, 1000 program

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)
      : ``
)

Apakah ini valid tergantung pada bagaimana tepatnya memahami aturan ketiga.

Ypnypn
sumber
Secara teknis ini bukan quine, karena ia mencetak versi modifikasi dari kode sumbernya sendiri daripada salinan yang identik. Itu memang menggunakan teknik seperti quine, jelas. Saya pikir kita perlu klarifikasi dari @TheTurtle.
JohnE
5
@ JohnE dan Ypnypn Ini adalah sesuatu yang saya bayangkan. Ini bekerja.
The Turtle
6
Anda masih jauh di bawah batas panjang kode. Mengapa Anda tidak mengubah 999 menjadi sesuatu yang lebih besar?
DankMemes
4

Ruby, 1,628 × 10 ^ 237 program

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

Pendekatan yang sama dengan jawaban Perl saya, tetapi karena Ruby sudah menangani int besar, lebih mudah untuk menyimpan sebagai hex.


Ruby, 9,277 × 10 ^ 90 program

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

Jadi upaya ini adalah variasi yang sedikit berbeda pada quine-like sebelumnya, tetapi karena semua fungsi tambahan, saya tidak mendapatkan jumlah yang mendekati setinggi yang lainnya ... Menarik untuk mencoba pendekatan lain!

Dom Hastings
sumber
4

Python 2, 9,7 * 10 ^ 229 program

O=0
if len(hex(O))<191:print"O=0x%x"%(O+1)+open(__file__).read()[-68:]
Biru
sumber
Bagus, tidak memikirkan pengulangan string!
Dom Hastings
2

C, 2,2 * 10 ^ 177 program

#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);})

Itu tidak sempurna, tapi cukup bagus. Maksud saya persis255 panjangnya byte dan menghasilkan program dengan panjang yang sama. Anda mungkin bisa bermain-main lagi untuk mendapatkan beberapa program lagi, tetapi saya akan membiarkannya seperti sekarang.

Program ini didasarkan pada quine C sederhana. Selain itu ada algoritma penghitungan yang cukup sederhana yang menghitung melalui semua nilai yang mungkin dari array char n. Kami memiliki program sebanyak permutasi stringn .

Rentang karakter dibatasi hingga rentang dari #(= 35) hingga [= (91). Itu karena saya tidak mau "atau\ dalam string, karena mereka perlu melarikan diri.

Pembuatan program berakhir ketika semua nilai dalam array char nadalah [. Kemudian ia mengeluarkan program boneka sederhana main(){}, yang dengan sendirinya tidak menghasilkan apa-apa.

#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);
})

Sebagai demonstrasi yang seharusnya berhasil, saya baru saja mengubah batas, jadi hanya karakter antara ASCII-Code 35dan36 digunakan dan hanya 4 elemen array.

Program yang dihasilkan adalah

% 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(){})

Ini output 2^4 + 1 = 17 program yang berbeda.

Jadi program di atas menghasilkan ((91-35)+1)^101 + 1 = 57^101 + 1 ~= 2.2 * 10^177program yang berbeda. Saya tidak yakin apakah ini penting, atau apakah perhitungan saya benar

MarcDefiant
sumber
1
Bisakah Anda memasukkan ini tentang 2.2 * 10^177(untuk mereka yang ingin membandingkan)?
flawr
Tidak tahu cara menghitung yang ini, tapi saya memasukkannya ;-)
MarcDefiant
wolframalpha.com =)
flawr
1

Perl, 1 × 10 ^ 163

Kalau tidak, ini adalah quine yang cukup mendasar, menyusut ke karakter sesedikit mungkin, yang hanya berjalan sementara counter tidak 0.

use bigint;$i=9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999||die;$_=<<'e';eval
print"use bigint;\$i=$i-1||die;\$_=<<'e';eval
${_}e
"
e
Dom Hastings
sumber
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#)))))
  • Ada 113 sembilan.
  • Program berikutnya memiliki 112 sembilan diikuti oleh 8
  • Program berikutnya memiliki 112 sembilan diikuti oleh 7
  • ...

Jumlah sembilan dibatasi oleh ukuran maksimum kode, 256, dengan mempertimbangkan ruang yang diperkenalkan oleh printer.

coredump
sumber
1

Perl, 1.4 * 10 ^ 225

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

Pendekatan serupa dengan python; hasil yang sama!

alexander-brett
sumber
0

> <> , 65534 (?) Program

Saya telah menambahkan tanda tanya di sebelah 65.533 karena saya belum memverifikasi bahwa ia dapat mencetak 65.533 (walaupun saya punya alasan untuk percaya seharusnya). Setelah saya punya sedikit waktu lagi, saya akan mencari cara untuk mengujinya.

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

Anda dapat mencobanya online di sini .

Inti dari program ini adalah bahwa ia mengubah output karakter di akhir dan kemudian mengurangi nilai numeriknya sebelum dicetak. Saya mendapat 65534 program karena nilai karakter ascii pada akhir kode adalah 65533, jadi menghitung program pertama kita memiliki 65534 (jika Anda menghitung program kosong 65535, saya kira). Program terakhir "kembali" bukanlah apa-apa; itu hanya berakhir ketika nilai karakter adalah 0.

Saya cukup yakin ini akan dapat mencetak karakter untuk semua iterasi: Saya tidak dapat menemukan sumber pasti untuk berapa banyak karakter> <> dapat dicetak, tetapi ada karakter langsung di bawah 65533, secara numerik.

Beri tahu saya jika ada masalah dengan implementasi ini; Saya sedikit tidak yakin tentang validitas entri saya.


Penjelasan

Saya tanpa malu-malu mencuri ide menggunakan tanda kutip tunggal untuk membuat pseudo-quine dari wiki> <> dan komentar yang pernah saya lihat di sini.

":?!;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 

Apa yang dilakukannya adalah mem-parsing semua setelah tanda kutip sebagai karakter, lalu kurangi yang terakhir. Dari sana hanya membalik tumpukan (sehingga untuk mencetak dalam urutan yang benar), mendorong tanda kutip ke tumpukan, dan kemudian mencetak hingga tumpukan kosong.

cole
sumber
0

Python, 1 × 10 ^ 194 program

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

Ini harus dijalankan dari file, bukan repl interaktif. Itu bukan quine.

Terima kasih kepada @The Turtle untuk membantu saya menghemat 3 byte, yang mana lebih banyak ruang untuk sembilan!
Terima kasih kepada @poke karena membantu saya menghemat 2 byte, yang mana lebih banyak ruang untuk sembilan!

Kekasih Keju
sumber
@ Cheese Lover The if n!=0itu mubazir. Anda bisa menulis if n.
The Turtle
Anda dapat menyingkirkan dua ruang juga; setelah if n:dan di antara replaceargumen.
colek
0

Bash, 52 program

Benar-benar tidak terinspirasi, dan (mudah-mudahan) solid di tempat terakhir.

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
Chris
sumber