Programları Yazdıran Bir Program


13

Meydan okuma

Amacınız başka bir program yazdıran bir program yazmaktır. Bu basılı program başka bir program yazdırmalı ve yeni program sonuna kadar başka bir program yazdırmalıdır.

kurallar

  1. Her program 256 bayttan az olmalıdır. (Bunun değiştirilmesi gerekiyorsa, bir yorum bırakın)
  2. Son program boş bir program olmalıdır.
  3. Sonlu sayıda program olmalıdır, bu nedenle program bir kınamak olamaz.
  4. Programların hepsi aynı dilde çalışmalıdır.
  5. Giriş yapılmasına izin verilmiyor.
  6. Kazanan program, olabildiğince çok program yazdırarak kendini sayan programdır.

İyi şanslar!


Maksimum puan 2^2048, veya 3.2317e616.
orlp

Daha kolay Büyük puanları karşılaştırmak için yapım için, forma puanı bir yaklaşma ekleyin a*10^bnerede 1<=a<10ve bdoğal bir sayıdır.
flawr

2
Aslında, önceki hesaplamam yanlıştı. Programın bayt cinsinden olması gerektiğinde, maksimum olası puan <yorum için sayı çok uzun> veya 1.2673e614.
orlp

Yanıtlar:


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

Tam skor: 254 219 + 254 192 + 254 166 + 254 140 + 254 114 + 254 88 + 254 63 + 254 38 + 254 13 + 3

Tüm programlar, dosya boyutu sınırına uymak için ISO-8859-1 kodlaması kullanılarak kaydedilmelidir.

@ChrisDrost sayesinde bir hata gösterdi ve yuvalama yaklaşımını önerdi.

CJam yorumlayıcısında çevrimiçi deneyin .

254 219 + 2 ≈ 4.56 x 10 526 programları

Puanın hat payı aşağıdaki çok daha basit program 1 ile elde edilebilir .

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

Bu programı çalıştırmak programı üretir

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

ve sonra 254 219 - 1 daha yineleme program

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

Bu son boş olmayan program bir hata 2 ile çıkar ve hiçbir şey yazdırmaz (boş program).

Nasıl çalışır

Dizenin zaten yığın üzerinde olduğunu varsayalım.

{      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 x 10 461 daha fazla program

İşte işler biraz deliriyor.

İlk program oldukça sıkıştırılabilir. Boş bir program yerine, yukarıdaki bölümden ilk programı üreten benzer bir program yazarak, skoru 254 192 program 3 ile geliştirebiliriz .

Program

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

önceki bölümün ilk programına benzer ve ilkini ve çıktısını 254 192 yinelemede çalıştırmak sonrakini üretir.

Dizenin zaten yığın üzerinde olduğunu varsayın:

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

Moar programları

Önceki bölümün ilk programı hala oldukça sıkıştırılabilir, bu nedenle benzer bir yöntem uygulayabilir ve 254 166 yinelemesinden sonra yukarıda belirtilen programı üreten bir program yazabiliriz .

255 bayt sınırına ulaşana kadar bu tekniği tekrar tekrar tekrarlamak için toplam 254 166 + 254 140 + 254 114 + 254 88 + 254 63 + 254 38 + 254 13 + 1 ≈ 1.59 × 10 399 program ekleyebiliriz. önceki bölümlerin.


1 Netlik için yeni satır eklendi.
2 Per Meta üzerinde konsensüs , bu varsayılan olarak izin verilir.
3 veya 0.000000000000000000000000000000000000000000000000000000000000000012%



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

Bunun geçerli olup olmadığı, üçüncü kuralı tam olarak nasıl anlayacağınıza bağlıdır.


Teknik olarak bir quine değildir , çünkü özdeş bir kopyadan ziyade kendi kaynak kodunun değiştirilmiş bir sürümünü yazdırır. Açıkçası kine benzeri teknikler kullanıyor. Sanırım @Turtle'dan açıklığa ihtiyacımız olacak.
JohnE

5
@JohnE ve Ypnypn Bu benim düşündüğüm bir şey. Bu çalışıyor.
Kaplumbağa

6
Hala kod uzunluğu sınırının çok altındasınız. 999'u neden daha büyük bir şeye değiştirmiyorsunuz?
10:15

4

Ruby, 1.628 × 10 ^ 237 program

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

Perl cevabımla aynı yaklaşım, ancak Ruby büyük ints'i zaten ele aldığı için hex olarak saklamak daha kolay.


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

Yani bu girişim, önceki kine benzeri üzerinde biraz farklı bir varyasyon, ancak tüm ekstra fonksiyonlar nedeniyle, diğeri kadar yüksek bir yere sayı almıyorum ... Yine de başka bir yaklaşım denemek ilginçti!


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:]

Güzel, dize tekrarı düşünmüyordu!
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);})

Mükemmel değil, ama oldukça iyi. Yani tam olarak 255bayt uzunluğunda ve aynı uzunlukta programlar üretiyor. Muhtemelen daha fazla program kazanmak için biraz daha etrafta dolaşabilirsiniz, ama şimdilik olduğu gibi bırakacağım.

Program basit bir C quine dayanmaktadır. Ayrıca, char dizisinin tüm olası değerlerini sayan oldukça basit bir sayma algoritması vardır n. Dizenin permütasyonları kadar çok programımız var n.

Karakter aralığı #(= 35) ila [= (91) aralığına sınırlandırılmıştır . Çünkü herhangi bir şey "veya \dizede istemiyorum , çünkü kaçmaları gerekiyor.

Karakter dizideki tüm değerleri, program kuşak uçları nvardır [. Daha sonra main(){}, kendisi hiçbir şey vermeyen basit bir kukla program çıkarır.

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

Çalışması gerektiğini bir gösteri olarak ben sadece sınırları değiştirdim, bu yüzden sadece ASCII-Code 35ve 36kullanılan karakterler ve sadece 4 dizi elemanları.

Ortaya çıkan programlar

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

Bu, 2^4 + 1 = 17farklı programlar verir.

Yani yukarıdaki program ((91-35)+1)^101 + 1 = 57^101 + 1 ~= 2.2 * 10^177farklı programlar çıkarır. Bunun önemli olup olmadığından veya hesaplamamın bile doğru olduğundan tamamen emin değilim


1
Lütfen bununla ilgili olduğunu 2.2 * 10^177(karşılaştırmak isteyenler için) ekler misiniz?
flawr

Bunu nasıl hesaplayacağımı bilmiyordum, ama dahil ettim ;-)
MarcDefiant


1

Perl, 1 × 10 ^ 163

Aksi takdirde, bu oldukça basit bir kınadır, mümkün olduğu kadar az karaktere küçültülür, bu sadece sayaç değilken çalışır 0.

use bigint;$i=9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999||die;$_=<<'e';eval
print"use bigint;\$i=$i-1||die;\$_=<<'e';eval
${_}e
"
e

1

Ortak 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 dokuz tane var.
  • Bir sonraki programda 112 dokuz ve ardından 8
  • Bir sonraki programda 112 dokuz ve ardından 7
  • ...

Dokuz sayısı , yazıcının getirdiği boşluklar dikkate alınarak maksimum kod boyutu 256 ile sınırlıdır .


1

Perl, 1.4 * 10 ^ 225

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

Python'a benzer yaklaşım; aynı sonuç!


0

> <> , 65534 (?) Programlar

65533 yazdırabilmem için henüz 65533'ün yanında bir soru işareti ekledim (buna inanmam için bir nedenim olmasına rağmen). Biraz daha zamanım olduğunda, bunu test etmenin bir yolunu bulacağım.

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

Burada çevrimiçi deneyebilirsiniz .

Bu programın özü, karakterin çıktısını en sonunda değiştirmesi ve ardından yazdırmadan önce sayısal değerini azaltmasıdır. 65534 programım var, çünkü kodun sonundaki karakterin ascii değeri 65533, bu yüzden ilk programı saydığımızda 65534'ümüz var (boş programı 65535'te sayıyorsanız, sanırım). Son "döndürülen" program hiçbir şey değildir; karakter değeri 0 olduğunda biter.

Tüm yinelemeler için bir karakter yazdırabileceğinden eminim:> <> kaç karakterin yazdırabileceğine dair kesin bir kaynak bulamadım, ancak sayısal olarak 65533'ün altında karakterler var.

Bu uygulamada herhangi bir sorun olup olmadığını bana bildirin; Girişimin geçerliliğinden biraz emin değilim.


açıklama

Ben> <> wiki ve burada bir kez gördüğüm bir yorum bir sahte-quine oluşturmak için tek bir tırnak işareti fikrini utanmadan çaldı.

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

Yaptığı şey, tırnak işaretinden sonraki her şeyi karakter olarak ayrıştırmak, sonra sonuncuyu azaltmaktır. Oradan sadece yığını tersine çevirir (doğru sırada yazdırmak için), yığının üzerine bir tırnak işareti iter ve ardından yığın boşalana kadar yazdırır.


0

Python, 1 × 10 ^ 194 program

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

Bu etkileşimli bir dosyadan değil , bir dosyadan çalıştırılmalıdır . Bir quine değil.

@ The Turtle sayesinde 3 bayt kurtarmama yardım etti, bu da dokuzlar için daha fazla alan!
Dokuzlar için daha fazla alan olan 2 bayt kaydetmeme yardımcı olduğu için @poke'a teşekkürler!


@ Cheese Lover if n!=0Gereksiz. Sadece yazabilirsiniz if n.
Kaplumbağa

İki alandan da kurtulabilirsiniz; sonra if n:ve replaceargümanlar arasında .
poke

0

Bash, 52 program

Tamamen yavan ve (umarım) son olarak sağlam bir şekilde.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.