Markov Chain Quine

17

Model Markov sederhana akan digunakan dalam pertanyaan ini. Untuk informasi lebih lanjut tentang Rantai Markov, lihat http://setosa.io/ev/markov-chains/ .

Ambil string. Untuk contoh ini, kita akan menggunakan kata:

reader

Sekarang, untuk setiap karakter, ambil karakter yang muncul setelah setiap kemunculan karakter dalam string. ( ​`^`​mewakili awal dari string dan ​`$`​mewakili akhir)

`^` -> {'r'}       # After the start of the string, there is an `r`.
'r' -> {'e', `$`}  # After the first `r` (*r*eader), there is an `e`
                   # after the second (reade*r*), there is the end of the string.
'e' -> {'a', 'r'}
'a' -> {'d'}
'd' -> {'e'}

Sekarang, mulai dari awal string, pilih secara acak dari salah satu karakter di set berikutnya. Tambahkan karakter ini dan kemudian pilih dari karakter di set berikutnya, dan seterusnya sampai Anda mencapai akhir. Berikut adalah beberapa contoh kata:

r
rereader
rer
readereader

Jika suatu karakter muncul setelah karakter lain beberapa kali, itu lebih cenderung untuk dipilih. Misalnya, dalam cocoa can, setelah a c, ada dua pertiga peluang untuk mendapatkan odan satu pertiga peluang mendapatkan a.

'c' -> {'o', 'o', 'a'}

Tantangan

Buat program yang tidak mengambil input dan menghasilkan string acak yang dihasilkan menggunakan Rantai Markov, seperti di atas, di mana input ke rantai adalah sumber program.

  1. Program harus memiliki setidaknya dua karakter, dua di antaranya harus sama (Untuk mencegah rantai "membosankan" yang hanya memiliki satu output)
  2. Anda dapat memodifikasi model untuk menggunakan byte alih-alih karakter jika Anda inginkan, tetapi ubah "karakter" menjadi "byte" pada aturan 1
  3. Program harus menghasilkan string secara acak dengan frekuensi yang diharapkan dalam teori

Ini , jadi program tersingkat menang!

Artyer
sumber
@ mbomb007 semua informasi ada dalam pertanyaan, tautannya hanya tambahan jika Anda tertarik (Ini adalah implementasi yang sangat mendasar)
Artyer
3
Mengapa ada ^dan $dalam tanda kutip? mungkin membuatnya lebih jelas untuk mengeluarkannya dari tanda kutip, atau menempatkannya dalam tanda kutip.
Lemon Destructible

Jawaban:

6

Pip , 64 byte

Ini sangat menyenangkan.

t:V Y\"m:"Yt@0T9=A OyY@>RC(t(Xy).'.)"ST["t:V Y"RPy";Vm"C9]\";Vm<tab>

<tab>mewakili karakter tab literal ( 0x09). Cobalah online!

Bagaimana?

TL; DR: escaped-string syntax, repr, dan eval.

Untuk string yang perlu mengandung "karakter literal , Pip telah lolos string , menggunakan \"sebagai pembatas. Quine standar menggunakan string yang lolos akan terlihat seperti ini:

V Y\""V Y".RPy\"

Yaitu: Yank (menyimpan sebagai y) string yang berisi "V Y".RPydan Vsebagainya itu. RPymengambil repr dari y, di mana kita menambahkan string literal V Y. Akhirnya, hasilkan hasil evaluasi.

Struktur quine Markov serupa, kecuali bahwa kita ingin menyimpan kode alih-alih mengeluarkannya dan kemudian melakukan beberapa hal dengannya. t:V Y\"...\"menugaskan hasil eval ke t. Di dalam kode eval'd, berikan m:"..."string kode m, yang akan kita evaluasi di akhir Vm.

ST["t:V Y"RPy";Vm"C9] membangun daftar yang berisi

"t:V Y"  Literal string
RPy      Repr(y)
";Vm"    Literal string
C9       Tab character

dan mengubahnya menjadi string, yang secara default menggabungkan semua item. Bagian ini setara dengan "V Y".RPydalam quine asli. Karena itu adalah ekspresi terakhir dalam string eval besar, nilainya adalah apa yang Vdikembalikan operator, dan dengan demikian apa yang ditugaskan t.

Dengan demikian, setelah eval dan penugasan, tsama dengan kode lengkap, dan mberisi

Yt@0T9=A OyY@>RC(t(Xy).'.)

Sekarang Vmmengevaluasi itu sebagai kode. Mari kita jabarkan apa yang terjadi.

                            We'll use y to hold the current character in the chain
Yt@0                        Yank first character of t into y (chain always starts there)
         Oy                 Output y without newline each time we...
    T9=A                    Loop till ASCII code of y equals 9 (tab)
                            Since there's only one literal tab, at the end of the program,
                              this satisfies the Markov chain ending requirement
                   Xy       Generate a regex that matches y
                  (  ).'.   Concatenate . to regex: now matches y followed by any character
                (t       )  Find all matches in t (returns a list)
              RC            Random choice from that list
           Y@>              Slice off the first character and yank the remaining one into y

Sepasang catatan:

  • Mengakhiri kode dengan tab literal lebih pendek daripada melakukan tes regex untuk "karakter berikutnya atau akhir string."
  • Regex yang saya gunakan tidak berfungsi dengan baik jika ada dua karakter dalam kode; misalnya, menerapkannya hanya xxyakan kembali xxdan tidak xydi pertandingan. Untungnya, bagaimanapun, tidak ada karakter ganda dalam kode ini, jadi tidak masalah.
DLosc
sumber
8

JavaScript, 217 215 byte

a="a=q;a=a.replace('q',uneval(a));for(b=c='a';d=a.split(c),c=d[Math.random()*~-d.length+1|0][0];b+=c);alert(b)";a=a.replace('q',uneval(a));for(b=c='a';d=a.split(c),c=d[Math.random()*~-d.length+1|0][0];b+=c);alert(b)

Perhatikan bahwa ini menggunakan uneval, yang hanya didukung oleh Firefox. Sampel berjalan:

a=ale(a.lend[Ma=d[Macepla.ler(b+=c)b=q;fom(a=q;a=dort(b+1|0],c);a.lit(a)
at(c=c;d[0],c=q;ath+1|0][0];dorerac=ac=d[Ma),c;)*~-d[Ma=alenepl(b+=ac=c;a=c;d[2];d.re(c;fom()
a="a[0],und=d=a)
angt(b),und=d.l(b=a)
a)
ale(a.rth.revanepleplit(b)
ac);fore(b)*~-d.r(b+1|0];fora';a)*~-d.splalith+=dorth+=c=";ath+=a.length+=';ale(b)
a.r(b=c=a)b+1|0],und[0][0];d.splerath.spleneva)";ath.r(ceneplith+=d=aceple(c;)*~-d=';ala';)b='ac;fom(b=c;a.ler(b=d=d[Ma.rt(c=cendor()*~-d='a=";ac;a.spla)b=ceva=';a=d.rt(angt(alength+1|0],c;angt()
al(ac=dorth+1|0][0][0][0][Ma.split()

Seperti yang Anda lihat, ini sebagian besar omong kosong, tapi itu yang diharapkan;) OP telah menciptakan JSFiddle yang menunjukkan bahwa peluang output JS yang valid secara sintaksis sekitar 6,3%.


Jika fungsi membaca sendiri diizinkan, ini bisa 78 byte ES6:

f=(c="f",p=("f="+f).split(c),q=p[Math.random()*~-p.length+1|0][0])=>q?c+f(q):c

Sangat, sangat jarang, ini menghasilkan JS yang valid secara sintaksis:

f=>e?c+f():c
f=>e?c=>engt():c
f=>e?c=(e):c
f=>e?c=>e=>ength.split():c
f=p=>q?c+f():c
f(q).sp=",p[Mat(q?c=(),plith.lith.sp.sp[0]).lendom().lith+f=>q=p.lendom(",p=p=>q?c+f():c
f(q),q?c=(c=(q)*~-p[0]):c
f().random(),q?c=(c=p[0]):c
f=>q?c=(q="+f"+f).rath.split(c):c
f="+1|0])=().lith.rat()*~-p=>q?c=p[Mat(c=",q?c=p.rath.splendom()*~-plength.splith.lendom(c):c

Favorit saya dari nama fungsi yang dibuatnya adalah .splendom()( split+ length+ random)

Produksi ETH
sumber
3
Saya bertanya-tanya berapa kemungkinan menghasilkan JavaScript yang valid ini. (Nerd snipe warning)
DanTheMan
2
@DanTheMan Tentu saja sangat, sangat rendah. Probabilitas semua tanda kurung dan tanda kurung seimbang sangat rendah. Meskipun satu kali saya dapatkan a.splerength.r(), yang bisa berlaku;)
ETHproduk
1
Mungkin ingin dicatat bahwa ini adalah FF hanya karena penggunaan yang tidak valid
Shaun H
1
@ShaunH Terima kasih, saya lupa bahwa hanya FF yang mendukung yang tidak valid.
ETHproduk
5
Fungsi membaca mandiri kedua tidak valid ( meta.codegolf.stackexchange.com/a/4878/48878 "quine tidak boleh mengakses sumbernya sendiri, secara langsung atau tidak langsung."), Dan @DanTheMan, menurut jsfiddle.net / kabkfLak / 1 , peluangnya harus sekitar 6,3%.
Artyer
5

Perl, 103 byte

Berdasarkan standar quine dan jawaban saya untuk pertanyaan ini :

$_=q{$_="\$_=q{$_};eval";@s='$';{push@s,(@n=/(?<=\Q$s[-1]\E)(.|$)/g)[rand@n];$s[-1]&&redo}print@s};eval

Contoh Output

$_=q{$_=q{$_=";@sh@s=";eval
$_="\$_=q{$_='$_=q{$_}pus=\$_=";@n=";@ndo};{pus=';edo};@n]\Q$_};{$_};@s=q{$_=';@s[rand@s=/g)(@s,(@s,(@sh@s[-1];@ndo};ed@s[-1]\E)(.|$_}prevan]&ral";evan];{$_}pus='$_};ed@sh@sh@s[-1]\$_='$_};evando};eval
$_=q{$_=";ed@s[-1];evand@s="\Q$_=";@s[-1]\Q$_=q{$_=";@nd@sh@sh@s='$_=q{$_=q{$_='$_="\Q$_='$_};{pus=\$_=q{$_}pral
$_=";evando};@nd@sh@s,(@n]\$_=";@s,(@s[-1];{$_=q{$_}pral
$_=";eval
$_='$_=q{$_="\$_="\Q$_=";ed@sh@s=\E)(.|$_=q{$_=q{$_=q{$_=q{$_}pus=/(?<=q{$_};eval
$_=";ed@sh@s[-1]\Q$_=';edo};{$_=q{$_=";@nt@s,(@n]&&&&&&&ral";@nd@s,(@s[-1]\$_}pus=\E)(.|$_=';@nt@s[ral

Mirip dengan pertanyaan lain, beberapa hasil menghasilkan Perl yang valid:

$_=q{$_};{$_};eval";@sh@s[-1]\$_='$_};evan]\Q$_}preval";eval
$_=q{$_};{$_=q{$_=';@nd@s=q{$_};@s[-1]\E)(@s[-1]\E)(@n=';edo};{$_}predo};eval
$_=q{$_=q{$_};edo};@n=q{$_=q{$_};@s[rin='$_=q{$_}pus=/g)(.|$_=q{$_};edo};eval
$_=q{$_};eval
$_=q{$_=";@ndo};{$_}preval

tetapi peluangnya sedikit lebih rendah, ~ 2%.

Dom Hastings
sumber
7
Jika Anda memberi tahu saya contoh pertama adalah Perl yang valid saya akan percaya Anda.
ankh-morpork
2
@ dohaqatar7 saya salah mengerti komentar Anda pada awalnya dan berpikir Anda tidak akan percaya jika saya mengatakan kode utama adalah valid Perl ...: D zoitz.com/comics/perl_small.png
Dom Hastings
@ ankh-morpork: jelas tidak valid, q{merupakan awal dari string literal dan tidak ada }untuk menutupnya. Perl sebenarnya cukup buruk dalam menjalankan urutan acak byte (dan ketika itu terjadi, biasanya karena string literal awal atau komentar).
4

Kode mesin MS-DOS (file .COM), 63 byte - tidak bersaing

Non-bersaing karena quine tidak boleh mengakses kode sumbernya sendiri.

Varian 126 byte akan memenuhi persyaratan "tidak mengakses kode sumbernya sendiri"!

Varian 63 byte terlihat seperti ini:

FC BE 00 01 AC 50 88 C2 B4 02 CD 21 E8 1A 00 59
4E AC 81 FE 3F 01 7C 03 BE 00 01 38 C1 75 F2 FE
CA 75 EE 81 FE 00 01 75 DB 8A 16 00 80 31 C0 8E
D8 31 C9 AC 00 C2 E2 FB 0E 1F 88 16 00 80 C3

Saya juga tidak yakin tentang distribusi probabilitas generator acak:

Program ini menggunakan fakta bahwa penghitung jam dan informasi lain yang dimodifikasi oleh interupsi disimpan di segmen 0 untuk menghasilkan angka acak.

Contoh untuk output yang dihasilkan adalah:

FC BE 00 01 7C 03 BE 00 80 C3

FC BE 00 01 38 C1 75 F2 FE 00 80 31 C9 AC 81 FE 00 80 C3

FC BE 00 01 38 C1 75 EE 81 FE 00 01 38 C1 75 EE 81 FE CA
75 F2 FE 00 01 75 F2 FE 00 80 C3

FC BE 00 C2 B4 02 CD 21 E8 1A 00 01 7C 03 BE 00 59 4E AC
81 FE 3F 01 AC 81 FE 3F 01 7C 03 BE 00 01 7C 03 BE 00 01
AC 81 FE 3F 01 7C 03 BE 00 80 C3

Dikonversi menjadi kode rakitan, programnya terlihat seperti ini:

    cld                # Ensure SI is being incremented
    mov si, 0x100      # Move SI to the first byte of the program
nextOutput:
    lodsb              # Load one byte of the program ...
    push ax            # ... save it to the stack ...
    mov dl, al         # ... and output it!
    mov ah, 2
    int 0x21
    call pseudoRandom  # Create a random number (in DL)
    pop cx             # Take the stored byte from the stack
    dec si             # Go back to the last byte loaded
nextSearch:
    lodsb              # Load the next byte
    cmp si, programEnd # If we loaded the last byte ...
    jl notEndOfProgram # ... the next byte to be loaded ...
    mov si, 0x100      # ... is the first byte of the program.
notEndOfProgram:
    cmp cl, al         # If the byte loaded is not equal to ...
                       # ... the last byte written then ...
    jne nextSearch     # ... continue at nextSearch!
    dec dl             # Decrement the random number and ...
    jnz nextSearch     # ... continue at nextSearch until the ...
                       # ... originally random number becomes zero.
    cmp si, 0x100      # If the last byte read was not the last byte ...
    jnz nextOutput     # ... of the program then output the next ...
                       # ... byte!

    # Otherwise fall through to the random number generator
    # whose "RET" instruction will cause the program to stop.        

    # The random number generator:
pseudoRandom:
    mov dl, [0x8000]   # Load the last random number generated
                       # (Note that this is uninitialized when
                       # this function is called the first time)
    xor ax, ax         # We use segment 0 which contains the ...
    mov ax, ds         # ... clock information and other data ...
                       # ... modified by interrupts!
    xor cx, cx         # Prepare for 0x10000 loops so ...
                       # ... all bytes in the segment are processed ...
                       # ... once and the value of SI will be ...
                       # ... unchanged in the end!
randomNext:
    lodsb              # Load one byte
    add dl, al         # Add that byte to the next random number
    loop randomNext    # Iterate over all bytes
    push cs            # Restore the segment
    pop ds
    mov [0x8000], dl   # Remember the random number
    ret                # Exit sub-routine

programEnd:
Martin Rosenau
sumber
Non-bersaing disediakan untuk jawaban yang memenuhi kriteria tantangan tetapi menggunakan bahasa atau fitur yang lebih baru daripada tantangan. Entah memposting varian yang tidak membaca sumbernya sendiri, atau menghapus jawabannya.
mbomb007
4

C, 306 328 585 611 615 623 673 707 byte

Kode sumber:

p[256][256]={0};char*X="p[256][256]={0};char*X=%c%s%c,Y[999],c,j,*a;main(){sprintf(Y,X,34,X,34);for(a=Y;*a;a++)p[*a][*(a+1)]++;for(j=*Y;putchar(c=j);)while(p[c][++j]<<16<rand());}",Y[999],c,j,*a;main(){sprintf(Y,X,34,X,34);for(a=Y;*a;a++)p[*a][*(a+1)]++;for(j=*Y;putchar(c=j);)while(p[c][++j]<<16<rand());}

Dengan baris baru dan spasi putih ditambahkan untuk keterbacaan / penjelasan:

01  p[256][256]={0};
02  char*X="p[256][256]={0};char*X=%c%s%c,Y[999],c,j,*a;main(){sprintf(Y,X,34,X,34);for(a=Y;*a;a++)p[*a][*(a+1)]++;for(j=*Y;putchar(c=j);)while(p[c][++j]<<16<rand());}",
03  Y[999],c,j,*a;
04  main(){
05      sprintf(Y,X,34,X,34);
06      for(a=Y;*a;a++)p[*a][*(a+1)]++;
07      for(j=*Y;putchar(c=j);)
08          while(p[c][++j]<<16<rand());
09  }

Penjelasan

Line 01: p[][]memegang hitungan satu karakter mengikuti yang lain.

Line 02: Xberisi sumber program, lolos dengan %c%s%c.

Line 03: Y akan berisi sumber literal program. c, j, *aAdalah variabel penghitungan.

Line 05: Setel Yuntuk berisi quine.

Line 06: Hitung kemunculan surat di p[][].

Line 07: Cetak status saat ini.

Line 08: Temukan karakter berikutnya secara acak, proporsional dengan jumlah pada p[][] .

Output sampel:

p[++);p[99]=Y;putfor(aind(a++j,*a+j=j,c][c,*an(arile(pr*Y,Y[256]<<1);)][*Y,Y;)wha+++j=*aintfor*Y;prin(a+j]=j][256<1)pr(a;a;f(p[char(Y;for());};a;ma;ma=%s%chain(Y;ar(j][256<<<1)p[256<<raile(cha][9]<rin(j,34,34,Y[256]+j,Y,34,Y,c=Y,*a;*a;for(){0}


sumber
1
Bisakah Anda menambahkan versi tanpa baris baru dan spasi sehingga kami dapat memverifikasi jumlah byte?
Steven H.
1
Ya, saya telah menambahkan versi baris tunggal di bagian atas.
3

Ruby, 152 byte

0;s="0;s=%p<<33
0until putc($/=Hash[[*(s%%s).chars.each_cons(2)].shuffle][$/])==?"<<33
0until putc($/=Hash[[*(s%s).chars.each_cons(2)].shuffle][$/])==?!

Output sampel:

0;s.c($/=Has(s).ears(2).ch[*(2)=Hacontc(2).ears.eas=Has==Hars%putc($/]).ears%sh_chuffl puns=Hachach[$/==?!

atau

0;s.ch[*($/=%pufl puns($/=%s.shas($/=Harsh_chutilears)])].e]).s)=Hac($/=="<<33\ntile].chufffle][[$/=Hars%sh_c(2)=%p<<<<<33
0;s)].ears)=Hars).c(s).eacon0un0;sh_c($/][*(s.s=Hacons=?!

Quines menggunakan pemformatan string melalui "s%s", dan melakukan rantai Markov dengan mengambil semua irisan dua karakter, mengocoknya, dan mengubahnya menjadi kamus Hash, di mana untuk kunci duplikat, penampilan terakhir menentukan nilai. Untuk menghindari menambahkan logika tambahan untuk permulaan, saya melacak karakter keluaran yang paling baru digunakan $/, yang secara otomatis diinisialisasi ke baris baru, dan memastikan bahwa baris baru selalu diikuti dalam kode dengan 0, karakter yang sama dengan kode dimulai. Untuk akhirnya, saya memanipulasi kode sumber sehingga hanya ada satu !sehingga kami selalu berakhir setelah bang, gunakan <<33untuk menambahkannya tanpa literal. Ini bisa di-golf lebih lanjut dengan menggunakan karakter satu digit yang tidak dapat dicetak dan bukannya ASCII 33, tetapi itu tampaknya terlalu menjengkelkan.

histokrat
sumber
4
p<<<<<33Operator super super super super? ;-)
ETHproduk
3
Itu adalah operator "waaaay kurang dari".
mbomb007
2
Saya suka kata-kata ini menghasilkan! Faktanya contoh pertama sangat memprihatinkan jika objek Has(s).ears(2)membuat saya tertawa!
Dom Hastings
2

Rust, 564 byte (tidak kompetitif)

extern crate rand;fn main(){let t=("extern crate rand;fn main(){let t=", ";let mut s=format!(\"{}{:?}{}\",t.0,t,t.1).into_bytes();s.push(0);let mut r=rand::thread_rng();let mut c=s[0];while c!=0{print!(\"{}\",c as char);let u=s.windows(2);c=rand::sample(&mut r,u.filter(|x|x[0]==c),1)[0][1];}}");let mut s=format!("{}{:?}{}",t.0,t,t.1).into_bytes();s.push(0);let mut r=rand::thread_rng();let mut c=s[0];while c!=0{print!("{}",c as char);let u=s.windows(2);c=rand::sample(&mut r,u.filter(|x|x[0]==c),1)[0][1];}}

Karena saya sudah menulis quine Rust yang cukup rapi untuk pertanyaan lain, saya pikir saya akan menyesuaikannya untuk ini, karena tampaknya cukup sederhana. Meskipun aslinya kecil, untuk ini saya telah berusaha sangat kecil untuk meminimalkan ukuran. Berikut ini adalah versi yang diperluas untuk menjelaskan apa yang terjadi:

// Random numbers are removed from the standard library in Rust,
// I had to make a cargo project to even compile this...
// Rust is hardly a golfing language.
extern crate rand;

fn main(){

    // The quine is fairly simple, we just make a tuple with 
    // "everything before this tuple" as first element, and
    // "everything after this tuple" with any quotes escaped 
    // as second. That makes it really easy to print.
    let t=("[...before...]", "[...after...]");

    // Instead of printing it, we save it as a byte vector
    // and append 0
    let mut s=format!("{}{:?}{}",t.0,t,t.1).into_bytes();
    s.push(0);

    // Start with the first character
    let mut c=s[0];
    let mut r=rand::thread_rng();

    while c!=0 {
        print!("{}",c as char);

        // We slide a 2 wide window over it to save a vector
        // of all bigrams. 
        let u=s.windows(2);

        // Filter it to only those which have the current character 
        // as first. Take one at random, its second is our next 
        // character.
        c=rand::sample(&mut r, u.filter(|x|x[0]==c), 1)[0][1];

        // Keep at it until the 0 byte is generated.
    }
}

Output sampel 1:

eran(),0{ller=samarin chas c).pr,teteran mut madoletet manthilaplerng().wind_byt.wit();let.u.0][*s=[*s.plleas.wshit, rnd:Vec<_byte mputextet ut t leat=r,t rant!=r().filllet rng();lar("{}{let.ind_byt.what amusarando_ramut!=st ct!(\").0]=colet!(&lec<_ret.plec=s.whrararandormpr=saile ret=r,0]=r);le(\"),t und;fint.prilt!();ler(2).forap(&ler=s(),t ut rat mu:t=ramund:Ve s.putec==[0];wst and_byt sh(\"et c s[1), munwhras[0];c=s=s="etornws(2)[0, ain(|x|x[0,0,0];fowile c ct(&l=",tes().co_byt().wrmat ash(|x|x[*s.lethrant.wrarmu.file(\"et, r==[1);uterile().0,t ando_rinwhas=[0{}"ect.wilant!("{ple mut, mut mamprmant,0];le(&lec=s.1),t co_>=fin mamustec!(\",c=[0];}}",0];leteteat.ust(",ternwhashrarmut ler("erat,0]==file and_reter==s.utet an letet.ut=", ras.1);fin("{:?}"et t letes[*sado_bytet rnd::Verain s[0];whant(){}{}\"echin s(2);lerad;wst reth(\",t u.iletermat c 1];}{}

Output sampel 2:

et!().0][0][0{}
Harald Korneliussen
sumber
2

Python 2, 211 byte

Keluarkan hasilnya ke stderr.

import random;X='q=[(list(t)+["$$"])[i+1]for i in range(len(t))if t[i]==c];c=random.choice(q)\nif c=="$$":exit(o)\no+=c\nexec X';s='import random;X=%r;s=%r;q=t=s%%(s,X);o=c="i";exec X';q=t=s%(s,X);o=c="i";exec X

Cobalah online

Output sampel:

i+[(s,X)));exenit(or;q=rt(t(t(t);o='ic\n(q)+1]=c\ndor randort))\ngeno));X)\nge(st))ic]=";oic=%ran(s%%(s%rt(q)\ngexe(s=st(t[(s=[if X=%(ompoiforanom;e(t X="$"$"ic="$"i";X=c rt X

Penjelasan singkat:

  • Program ini menggunakan s='s=%r;print s%%s';print s%sformat quine. Saya membuat string s, yang akan berisi seluruh program.
  • String Xberisi prosedur untuk mengeksekusi secara rekursif.
  • Prosedur membangun string output o , yang akan dicetak stderrsetelah mencapai akhir rantai Markov.
  • Ujung rantai diwakili oleh string $$ , menggunakan dua karakter sehingga program akan bekerja untuk semua string. Saya bisa menggunakan karakter yang tidak ada dalam program saya chr(0), tapi saya pikir itu lebih lama.
  • Karakter yang dipilih setiap eksekusi ditempatkan c , yang (bersama dengan o) diinisialisasi ke karakter pertama dari program.
  • Daftar karakter yang mengikuti setiap kemunculan pilihan cdalam string t(variabel yang menahan quine dari kode sumber) adalah q, yang akan dipilih dari untuk pemilihan berikutnya c.
mbomb007
sumber
1

PHP, 144 135 130 120 272 220 212 byte

<?$e='$p=$n="";foreach(str_split($s)as$w)$p=$m[$p][]=$w;do echo$n=$m[$n][array_rand($m[$n])];while("\n"!=$n);
';$s='<?$e=%c%s%1$c;$s=%1$c%s%1$c;$s=sprintf($s,39,$e,$s);eval($e);';$s=sprintf($s,39,$e,$s);eval($e);

Atau, diformat untuk dibaca:

<?$e='$p = $n = "";
foreach (str_split($s) as $w) {
    $p = $m[$p][] = $w;
}
do {
    echo $n = $m[$n][array_rand($m[$n])];
} while ("\n" != $n);
';$s='<?$e=%c%s%1$c;$s=%1$c%s%1$c;$s=sprintf($s,39,$e,$s);eval($e);';$s=sprintf($s,39,$e,$s);eval($e);

Output sampel:

<?p=')ay_r_gecorr_splililen]=$p=$w;

dan:

<?p=$n=$ntststs$m[$n=$m[ay_r_chondo$n=$ph(s$nt(fitstr_r_geantentr_s('m[$n=$n"!=$p etstsp][$w;d(fililile(s$w)$nt(sphor_str_getrarast(''''m[$n='m[$m';

dan:

<?p=$who eay_re($n=$n=$nt(')];d(fililileando et($m[]=$pleay_ch(')aray_ren='''))ay_st_r_s($m[$m[asp])ay_co$m[$p $phorentechitr_rean)][$n=$nd("\n"!=$n=$wh(filend('')ay_gen=$ndo$nt_rasp=$n][$p=$whp=$n='m[$n"\n)))))][$w;dorechph(';dorracho$ple_s$w;fil

dan:

<?ph($n);

Kecurangan PHP, 117

Bagi yang penasaran, jika kita menipu dengan membaca sumber kita sendiri, kita bisa melakukan 117:

<?=$p=$n='';foreach(str_split(file('m')[0])as$w)$p=$m[$p][]=$w;do echo$n=$m[$n][array_rand($m[$n])];while("\n"!=$n);
Payung
sumber
Selamat datang di situs ini! Sayangnya kami memiliki beberapa aturan tentang apa yang dianggap sebagai Quine yang tepat untuk tantangan seperti ini dan sayangnya membaca dari sumber Anda sendiri dilarang.
Post Rock Garf Hunter
Oh, bagus, terima kasih. Saya sedang mencari aturan. Saya harus merevisi ini.
Payung