มาร์คอฟเชนควิน


17

คำถามมาร์คอฟแบบง่ายจะใช้ในคำถามนี้ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับโซ่มาร์คอฟดูhttp://setosa.io/ev/markov-chains/

ใช้สตริง สำหรับตัวอย่างนี้เราจะใช้คำว่า:

reader

ทีนี้สำหรับตัวละครแต่ละตัวให้นำตัวละครที่ปรากฏหลังตัวละครแต่ละตัวในสตริง ( ​`^`​หมายถึงจุดเริ่มต้นของสตริงและ​`$`​แสดงถึงจุดสิ้นสุด)

`^` -> {'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'}

ตอนนี้เริ่มจากจุดเริ่มต้นของสตริงเลือกสุ่มจากหนึ่งในตัวละครในชุดถัดไป ผนวกอักขระนี้แล้วเลือกจากตัวละครในชุดถัดไปและต่อไปเรื่อย ๆ จนกว่าคุณจะไปจนจบ นี่คือตัวอย่างคำ:

r
rereader
rer
readereader

หากตัวละครปรากฏขึ้นหลังจากตัวละครอื่นหลายครั้งก็มีแนวโน้มที่จะเลือก ยกตัวอย่างเช่นในcocoa canหลังจากที่cมีสองในสามของโอกาสในการได้รับการอื่นoและมีโอกาส 1/3 aของรับ

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

ท้าทาย

สร้างโปรแกรมที่ไม่มีอินพุตและเอาต์พุตสตริงแบบสุ่มที่สร้างโดยใช้ Markov Chain เช่นด้านบนซึ่งอินพุตไปยัง chain เป็นซอร์สของโปรแกรม

  1. โปรแกรมต้องมีอักขระอย่างน้อยสองตัวซึ่งสองตัวต้องเหมือนกัน (เพื่อป้องกันโซ่ "น่าเบื่อ" ที่มีเพียงหนึ่งเอาต์พุต)
  2. คุณสามารถปรับเปลี่ยนรูปแบบเพื่อใช้ไบต์แทนอักขระได้หากต้องการ แต่เปลี่ยน "อักขระ" เป็น "ไบต์" ในกฎ 1
  3. โปรแกรมควรส่งออกสตริงแบบสุ่มกับความถี่ที่คาดหวังในทางทฤษฎี

นี่คือดังนั้นโปรแกรมที่สั้นที่สุดชนะ!


@ mbomb007 ข้อมูลทั้งหมดอยู่ในคำถามลิงค์เป็นพิเศษถ้าคุณได้รับความสนใจ (นี่คือการดำเนินการขั้นพื้นฐานมาก)
Artyer

3
ทำไม^และ$ในเครื่องหมายคำพูด? มันอาจทำให้ชัดเจนมากขึ้นที่จะนำออกจากคำพูดหรือใส่ไว้ใน backquotes
เลมอนที่ถูกทำลายได้

คำตอบ:


6

Pip , 64 ไบต์

มันสนุกมาก

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

<tab>แสดงถึงตัวอักษรแท็บตัวอักษร ( 0x09) ลองออนไลน์!

อย่างไร?

TL; DR: ไวยากรณ์สตริง escaped, repr และ eval

สำหรับสตริงที่จำเป็นต้องมีตัวอักษร"ตัวอักษร Pip ได้หนีออกมาสตริงใช้\"เป็นตัวคั่น ควินมาตรฐานที่ใช้สตริงที่ใช้ Escape จะมีลักษณะดังนี้:

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

นั่นคือ: Yank (การจัดเก็บเป็นy) สตริงที่มี"V Y".RPyและVมัน RPyใช้เวลา Repr ของเพื่อที่เราย่อหน้าสายอักขระตัวอักษรy V Yในที่สุดผลลัพธ์ของผลลัพธ์ eval

โครงสร้างของ Markov Quine นั้นคล้ายกันยกเว้นว่าเราต้องการบันทึกรหัสแทนที่จะแสดงผลแล้วทำบางสิ่งกับมันหลังจากนั้น t:V Y\"...\"กำหนดผล EVAL tไป ภายในรหัส eval'd ที่m:"..."กำหนดสตริงของรหัสซึ่งเราจะประเมินในตอนท้ายด้วยmVm

ST["t:V Y"RPy";Vm"C9] สร้างรายการที่มี

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

และแปลงเป็นสตริงซึ่งโดยค่าเริ่มต้นจะเชื่อมรายการทั้งหมด ส่วนนี้เทียบเท่ากับ"V Y".RPyใน quine ดั้งเดิม เพราะมันคือการแสดงออกสุดท้ายในสตริง EVAL ใหญ่ค่าของมันคือสิ่งที่ผลตอบแทนที่ผู้ประกอบการและทำให้สิ่งที่ได้รับมอบหมายให้Vt

ดังนั้นหลังจาก eval และการมอบหมายtเท่ากับรหัสเต็มและmมี

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

ตอนนี้Vmประเมินว่าเป็นรหัส ลองแยกแยะว่าเกิดอะไรขึ้น

                            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

หมายเหตุคู่:

  • การสิ้นสุดโค้ดด้วยแท็บตัวอักษรนั้นสั้นกว่าการทดสอบ regex สำหรับ "ตัวอักษรถัดไปหรือจุดสิ้นสุดของสตริง"
  • regex ที่ฉันใช้ไม่ทำงานอย่างถูกต้องหากมีตัวอักษรสองเท่าในรหัส; ตัวอย่างเช่นการนำไปใช้เพื่อxxyจะกลับมาเท่านั้นxxและไม่ได้xyอยู่ในการแข่งขัน อย่างไรก็ตามโชคดีที่ไม่มีตัวอักษรเพิ่มเป็นสองเท่าในรหัสนี้ดังนั้นจึงไม่สำคัญ

8

JavaScript, 217 215 ไบต์

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)

โปรดทราบว่าสิ่งนี้ใช้unevalซึ่งรองรับโดย Firefox เท่านั้น ตัวอย่างการวิ่ง:

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()

อย่างที่คุณเห็นมันส่วนใหญ่เป็นการพูดพล่อยๆ แต่เป็นสิ่งที่คาดหวัง;) OP ได้สร้างJSFiddleซึ่งแสดงให้เห็นว่าโอกาสของการส่งออกที่ถูกต้องของ syntactically


หากอนุญาตให้ฟังก์ชั่นอ่านตัวเองนี่อาจเป็น 78 ไบต์ของ ES6:

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

มากไม่ค่อยมากผลลัพธ์นี้ JS ที่ถูกต้องทางไวยากรณ์:

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

ชื่อฟังก์ชั่นที่ฉันชอบที่สร้างขึ้นคือ.splendom()( split+ length+ random)


3
ฉันสงสัยว่าความน่าจะเป็นของ JavaScript ที่ถูกต้องนี้คืออะไร (คำเตือนนกปากซ่อม Nerd)
DanTheMan

2
@ DanTheMan แน่นอนมากต่ำมาก ความน่าจะเป็นของวงเล็บและวงเล็บทั้งหมดที่มีความสมดุลนั้นต่ำมากอย่างไม่น่าเชื่อ แม้ว่าครั้งหนึ่งฉันจะได้รับa.splerength.r()ซึ่งอาจใช้ได้;)
ETHproductions

1
อาจต้องการทราบว่านี่เป็น FF เท่านั้นเนื่องจากการใช้งานที่ไม่ปกติ
Shaun H

1
@ShaunH ขอบคุณฉันลืมไปแล้วว่ามีเพียง FF เท่านั้นที่รองรับการทำงานแบบไม่ได้มาตรฐาน
ETHproductions

5
ฟังก์ชั่นการอ่านตัวเองครั้งที่สองไม่ถูกต้อง ( meta.codegolf.stackexchange.com/a/4878/48878 "ควินจะต้องไม่เข้าถึงแหล่งข้อมูลของตัวเองไม่ว่าโดยตรงหรือโดยอ้อม") และ @DanTheMan ตามjsfiddle.net / kabkfLak / 1โอกาสน่าจะอยู่ที่ 6.3%
Artyer

5

Perl, 103 ไบต์

ตาม quine มาตรฐานและคำตอบของฉันสำหรับคำถามนี้ :

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

ตัวอย่างผลลัพธ์

$_=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

เช่นเดียวกับคำถามอื่น ๆ ผลลัพธ์บางอย่างสร้าง Perl ที่ถูกต้อง:

$_=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

แต่โอกาสจะลดลงเล็กน้อยที่ ~ 2%


7
ถ้าคุณบอกฉันตัวอย่างแรกคือ Perl ที่ถูกต้องฉันจะเชื่อคุณ
ankh-morpork

2
@ dohaqatar7 ฉันเข้าใจผิดความคิดเห็นของคุณในตอนแรกและคิดว่าคุณจะไม่เชื่อฉันถ้าฉันบอกว่ารหัสหลักคือ Perl ที่ถูกต้อง ... : D zoitz.com/comics/perl_small.png
Dom Hastings

@ ankh-morpork: มันไม่ถูกต้องชัดเจนว่าq{เป็นจุดเริ่มต้นของตัวอักษรสตริงและไม่มี}การปิด Perl ของจริงค่อนข้างไม่ดีในการใช้ลำดับแบบสุ่มของไบต์ (และเมื่อมันทำมันเป็นปกติเนื่องจากสตริงตัวอักษรหรือความคิดเห็นก่อน)

4

รหัสเครื่อง MS-DOS (ไฟล์. COM), 63 ไบต์ - ไม่สามารถแข่งขันได้

ไม่แข่งขันเนื่องจากควินจะต้องไม่เข้าถึงซอร์สโค้ดของตัวเอง

ตัวแปรขนาด 126 ไบต์จะตอบสนองความต้องการ "ไม่เข้าถึงซอร์สโค้ดของตัวเอง"!

ตัวแปร 63 ไบต์มีลักษณะดังนี้:

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

ฉันยังไม่แน่ใจเกี่ยวกับการแจกแจงความน่าจะเป็นของตัวสร้างแบบสุ่ม:

โปรแกรมใช้ข้อเท็จจริงที่ว่าตัวนับนาฬิกาและข้อมูลอื่น ๆ ที่ถูกแก้ไขโดยอินเตอร์รัปต์ถูกเก็บไว้ในเซกเมนต์ 0 เพื่อสร้างตัวเลขสุ่ม

ตัวอย่างของผลลัพธ์ที่สร้างขึ้นคือ:

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

เปลี่ยนเป็นรหัสชุดประกอบโปรแกรมจะมีลักษณะดังนี้:

    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:

การไม่แข่งขันถูกสงวนไว้สำหรับคำตอบที่ตรงกับเกณฑ์ความท้าทาย แต่ใช้ภาษาหรือคุณสมบัติใหม่กว่าความท้าทาย โพสต์ชุดตัวเลือกที่ไม่ได้อ่านซอร์สของตัวเองหรือลบคำตอบ
mbomb007

4

C, 306 328 585 611 615 623 673 707 ไบต์

รหัสแหล่งที่มา:

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

ด้วยการขึ้นบรรทัดใหม่และพื้นที่ว่างเพิ่มเพื่อความชัดเจน / คำอธิบาย:

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  }

คำอธิบาย

Line 01: p[][]เก็บจำนวนอักขระหนึ่งตัวที่ตามมาอีกตัว

Line 02: มีแหล่งที่มาของโปรแกรมหนีไปกับX%c%s%c

Line 03: Yจะมีแหล่งที่มาที่แท้จริงของโปรแกรม c, j, *aเป็นตัวแปรนับ

Line 05: ตั้งค่าYให้มีควิน

Line 06: p[][]เกิดขึ้นในจดหมายจำนวน

Line 07: พิมพ์สถานะปัจจุบัน

Line 08: p[][]ค้นหาตัวอักษรถัดไปสุ่มสัดส่วนกับการนับจำนวนใน

ตัวอย่างผลลัพธ์:

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}


1
คุณสามารถเพิ่มรุ่นที่ไม่มีบรรทัดใหม่และพื้นที่ว่างเพื่อให้เราสามารถตรวจสอบจำนวนไบต์ได้หรือไม่
Steven H.

1
ใช่ฉันเพิ่มรุ่นบรรทัดเดียวที่ด้านบน

3

ทับทิม 152 ไบต์

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][$/])==?!

ตัวอย่างผลลัพธ์:

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

หรือ

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 โดยใช้การจัดรูปแบบสตริงผ่าน"s%s"และทำ Markov chaining โดยนำอักขระสองชิ้นทั้งหมดมาสับและเปลี่ยนเป็นพจนานุกรม Hash โดยคีย์ที่ซ้ำกันจะปรากฏค่าสุดท้าย เพื่อหลีกเลี่ยงการเพิ่มตรรกะพิเศษสำหรับการเริ่มต้นฉันติดตามอักขระเอาต์พุตล่าสุดที่ใช้$/ซึ่งเริ่มต้นโดยอัตโนมัติในการขึ้นบรรทัดใหม่และตรวจสอบให้แน่ใจว่ามีการขึ้นบรรทัดใหม่ในโค้ดเสมอโดย0อักขระเดียวกันกับรหัสที่ขึ้นต้นด้วย ในตอนท้ายฉันจัดการซอร์สโค้ดเพื่อให้มีเพียงอันเดียว!ดังนั้นเราจึงสิ้นสุดหลังจากการปังโดยใช้<<33เพื่อเพิ่มโดยไม่ต้องมีตัวอักษร สิ่งนี้สามารถเล่นกอล์ฟได้มากขึ้นโดยใช้อักขระตัวเลขเดียวที่ไม่สามารถพิมพ์ได้แทน ASCII 33 แต่ดูเหมือนจะน่ารำคาญเกินไป


4
p<<<<<33ผู้ประกอบการ super-super-super-super-concat? ;-)
ETHproductions

3
นั่นเป็นตัวดำเนินการ "waaaay น้อยกว่า"
mbomb007

2
ฉันชอบคำนี้ที่สร้าง! ความจริงตัวอย่างแรกคือความกังวลถ้าวัตถุHas(s).ears(2)ทำให้ฉันหัวเราะหึ ๆ !
Dom Hastings

2

สนิม 564 ไบต์ (ไม่แข่งขัน)

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];}}

เนื่องจากฉันได้เขียน Rust quine ที่เรียบร้อยแล้วสำหรับคำถามอื่นฉันคิดว่าฉันจะปรับมันสำหรับเรื่องนี้เพราะมันดูเรียบง่ายพอ ในขณะที่ต้นฉบับมีขนาดเล็ก แต่สำหรับสิ่งนี้ฉันได้พยายามเล็กน้อยเพื่อลดขนาด ต่อไปนี้เป็นรุ่นขยายเพื่ออธิบายสิ่งที่เกิดขึ้น:

// 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.
    }
}

ตัวอย่างผลลัพธ์ 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];}{}

ตัวอย่างผลลัพธ์ 2:

et!().0][0][0{}

2

Python 2, 211 ไบต์

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

ลองออนไลน์

ตัวอย่างผลลัพธ์:

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

คำอธิบายสั้น ๆ :

  • โปรแกรมนี้ใช้s='s=%r;print s%%s';print s%sรูปแบบควิน ฉันสร้างสตริงsซึ่งจะมีทั้งโปรแกรม
  • สตริงXมีโพรซีเดอร์ในการเรียกใช้ซ้ำ
  • ขั้นตอนการสร้างสตริงผลลัพธ์oซึ่งจะถูกพิมพ์ไปstderrเมื่อถึงจุดสิ้นสุดของห่วงโซ่มาร์คอฟ
  • จุดสิ้นสุดของห่วงโซ่จะถูกแทนด้วยสตริง$$โดยใช้อักขระสองตัวเพื่อให้โปรแกรมทำงานกับสตริงทั้งหมด ฉันสามารถใช้ตัวละครไม่ใช่ในโปรแกรมของฉันเหมือนchr(0)แต่ฉันคิดว่ามันนานกว่านี้
  • อักขระที่เลือกไว้สำหรับการดำเนินการแต่ละครั้งจะถูกวางไว้cซึ่ง (พร้อมกับo) จะเริ่มต้นเป็นอักขระตัวแรกของโปรแกรม
  • รายการของตัวละครที่เป็นไปตามการเกิดขึ้นของแต่ละทางเลือกcในสตริงt(ตัวแปรที่ถือควินของรหัสที่มา) เป็นที่จะได้รับเลือกจากตัวเลือกต่อไปของqc

1

PHP, 144 135 130 120 272 220 212 ไบต์

<?$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);

หรือจัดรูปแบบเพื่อให้สามารถอ่านได้:

<?$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);

ตัวอย่างผลลัพธ์:

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

และ:

<?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';

และ:

<?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

และ:

<?ph($n);

PHP Cheating, 117

สำหรับคนที่อยากรู้อยากเห็นถ้าเราโกงโดยอ่านแหล่งข้อมูลของเราเองเราสามารถทำได้ 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);

ยินดีต้อนรับสู่เว็บไซต์! น่าเสียดายที่เรามีกฎบางอย่างเกี่ยวกับสิ่งที่นับว่าเป็นควินที่เหมาะสมสำหรับความท้าทายเช่นนี้และเป็นสิ่งต้องห้ามที่อ่านจากแหล่งที่มาของคุณเอง
โพสต์ร็อค Garf Hunter

โอ้ดีขอบคุณ ฉันกำลังมองหากฎ ฉันจะต้องแก้ไขสิ่งนี้
ร่ม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.