Markov Chain Quine

17

In dieser Frage wird ein einfaches Markov-Modell verwendet. Weitere Informationen zu Markov-Ketten finden Sie unter http://setosa.io/ev/markov-chains/ .

Nimm eine Schnur. In diesem Beispiel verwenden wir das Wort:

reader

Nehmen Sie nun für jedes Zeichen die Zeichen, die nach jedem Auftreten des Zeichens in der Zeichenfolge erscheinen. ( ​`^`​Stellt den Anfang der Zeichenfolge und ​`$`​das Ende dar)

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

Wählen Sie nun, beginnend mit dem Anfang der Zeichenfolge, zufällig eines der Zeichen im nächsten Satz aus. Hängen Sie dieses Zeichen an und wählen Sie dann aus den Zeichen der nächsten Gruppe usw. aus, bis Sie das Ende erreicht haben. Hier sind einige Beispielwörter:

r
rereader
rer
readereader

Wenn ein Zeichen mehrmals nach einem anderen Zeichen erscheint, ist es wahrscheinlicher, dass es ausgewählt wird. Zum Beispiel besteht cocoa cannach a ceine Wahrscheinlichkeit von zwei Dritteln und eine Wahrscheinlichkeit von oeinem Drittel a.

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

Herausforderung

Erstellen Sie ein Programm, das keine Eingabe akzeptiert und eine zufällige Zeichenfolge ausgibt, die mit einer Markov-Kette wie oben generiert wurde, wobei die Eingabe in die Kette die Quelle des Programms ist.

  1. Das Programm muss aus mindestens zwei Zeichen bestehen, von denen zwei gleich sein müssen (um zu verhindern, dass Ketten langweilig werden, die nur eine Ausgabe haben)
  2. Sie können das Modell so ändern, dass Bytes anstelle von Zeichen verwendet werden. Ändern Sie jedoch in Regel 1 "Zeichen" in "Bytes"
  3. Das Programm sollte Strings zufällig mit der theoretisch erwarteten Häufigkeit ausgeben

Das ist , also gewinnt das kürzeste Programm!

Artyer
quelle
@ mbomb007 alle Informationen sind in der Frage, der Link ist nur extra, wenn Sie interessiert sind (Dies ist eine sehr einfache Implementierung)
Artyer
3
Warum stehen die ^und $in Anführungszeichen? es könnte klarer sein, es aus Anführungszeichen zu entfernen oder sie in Anführungszeichen zu setzen.
Destructible Lemon

Antworten:

6

Pip , 64 Bytes

Das hat Spaß gemacht.

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

<tab>steht für ein literales Tabulatorzeichen ( 0x09). Probieren Sie es online!

Wie?

TL; DR: Escapezeichenfolgensyntax, Repr und Eval.

Für Zeichenfolgen, die Literalzeichen enthalten müssen ", hat Pip Zeichenfolgen maskiert mit Escapezeichen \"als Trennzeichen versehen. Ein Standard-Quine mit maskierten Zeichenfolgen würde folgendermaßen aussehen:

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

Das heißt: Yank (Speichern als y) eine Zeichenfolge mit "V Y".RPyund eV . RPyNimmt den Repräsentanten y, dem wir die wörtliche Zeichenfolge voranstellen V Y. Zuletzt geben Sie das Ergebnis der Auswertung aus.

Die Struktur der Markov-Quine ist ähnlich, außer dass wir den Code speichern wollen, anstatt ihn auszugeben, und danach einige Dinge damit machen wollen. t:V Y\"...\"weist das Bewertungsergebnis zu t. Weist im eval'd-Code m:"..."eine Code-Zeichenfolge zu m, die wir am Ende mit auswertenVm .

ST["t:V Y"RPy";Vm"C9] erstellt eine Liste mit

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

und konvertiert es in eine Zeichenfolge, die standardmäßig alle Elemente verkettet. Dieser Abschnitt entspricht"V Y".RPy dem Originalquine. Da es sich um den letzten Ausdruck in der Big-Eval-Zeichenfolge handelt, gibt der VOperator den Wert zurück und wird diesem zugewiesent .

Also, nach der Auswertung und Zuordnung, t gleich der vollständige Code und menthält

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

Jetzt Vm wertet das als Code aus. Lassen Sie uns zusammenfassen, was passiert.

                            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

Ein paar Notizen:

  • Das Beenden des Codes mit einem wörtlichen Tabulator war kürzer als ein Regex-Test für "nächstes Zeichen oder Ende der Zeichenfolge".
  • Der von mir verwendete reguläre Ausdruck funktioniert nicht ordnungsgemäß, wenn der Code doppelte Zeichen enthält. Wenn Sie es beispielsweise auf anwenden, wird es xxynur xxund nicht xyin den Übereinstimmungen zurückgegeben. Glücklicherweise enthält dieser Code jedoch keine doppelten Zeichen, sodass es keine Rolle spielt.
DLosc
quelle
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)

Beachten Sie, dass dies verwendet uneval, was nur von Firefox unterstützt wird. Probeläufe:

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

Wie Sie sehen, ist es meistens Kauderwelsch, aber das ist zu erwarten;) Das OP hat eine JSFiddle erstellt, die zeigt, dass die Wahrscheinlichkeit, dass eine Ausgabe syntaktisch gültig ist, bei 6,3% liegt.


Wenn Selbstlesefunktionen zulässig wären, könnten dies 78 Byte von ES6 sein:

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

Sehr, sehr selten gibt dies syntaktisch gültiges JS aus:

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

Mein Favorit der erstellten Funktionsnamen ist .splendom()( split+ length+ random)

ETHproductions
quelle
3
Ich frage mich, wie hoch die Wahrscheinlichkeit ist, dass dabei gültiges JavaScript generiert wird. (Nerd-Snipe-Warnung)
DanTheMan
2
Sicherlich sehr, sehr niedrig. Allein die Wahrscheinlichkeit, dass alle Klammern und Klammern ausgeglichen sind, ist unglaublich gering. Obwohl ich einmal bekommen habe a.splerength.r(), was gültig sein könnte;)
ETHproductions
1
Vielleicht möchten Sie feststellen, dass dies FF nur aufgrund der Verwendung von Uneval ist
Shaun H
1
@ShaunH Danke, ich habe vergessen, dass nur FF uneval unterstützt.
ETHproductions
5
Die zweite Selbstlesefunktion ist nicht gültig ( meta.codegolf.stackexchange.com/a/4878/48878 "ein Quine darf weder direkt noch indirekt auf seine eigene Quelle zugreifen.") Und @DanTheMan, so jsfiddle.net / kabkfLak / 1 sollte die Chance bei 6,3% liegen.
Artyer
5

Perl, 103 Bytes

Basierend auf der Standard-Quine und meiner Antwort auf diese Frage :

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

Beispielausgabe

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

Ähnlich wie bei der anderen Frage generieren einige Ergebnisse gültiges 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

Die Chancen sind jedoch mit ~ 2% etwas geringer.

Dom Hastings
quelle
7
Wenn Sie mir sagen würden, das erste Beispiel sei gültiges Perl, würde ich Ihnen glauben.
Ankh-Morpork
2
@ dohaqatar7 Ich habe Ihren Kommentar zuerst missverstanden und dachte, Sie würden mir nicht glauben, wenn ich sagen würde, der Hauptcode sei gültig Perl ...: D zoitz.com/comics/perl_small.png
Dom Hastings
@ ankh-morpork: es ist eindeutig ungültig, q{ist der Beginn eines String-Literal und es gibt keine Möglichkeit, es }zu schließen. Perl ist eigentlich ziemlich schlecht darin, zufällige Sequenzen von Bytes auszuführen (und wenn dies der Fall ist, liegt dies normalerweise an einem frühen String-Literal oder Kommentar).
4

MS-DOS-Computercode (COM-Datei), 63 Byte - nicht konkurrierend

Nicht konkurrierend, da ein Quine nicht auf seinen eigenen Quellcode zugreifen darf.

Eine 126-Byte-Variante würde die Anforderung "nicht auf eigenen Quellcode zugreifen" erfüllen!

Die 63-Byte-Variante sieht folgendermaßen aus:

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

Ich bin mir auch nicht sicher über die Wahrscheinlichkeitsverteilung des Zufallsgenerators:

Das Programm nutzt die Tatsache, dass die Taktzähler und andere durch Interrupts veränderte Informationen in Segment 0 gespeichert werden, um Zufallszahlen zu generieren.

Beispiele für generierte Ausgaben sind:

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

In Assembler-Code konvertiert sieht das Programm so aus:

    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
quelle
Das Nicht-Konkurrieren ist Antworten vorbehalten, die die Herausforderungskriterien erfüllen, jedoch eine Sprache oder ein Feature verwenden, das neuer ist als die Herausforderung. Schreiben Sie entweder die Variante, die ihre eigene Quelle nicht liest, oder löschen Sie die Antwort.
mbomb007
4

C 306 328 585 611 615 623 673 707 Bytes

Quellcode:

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

Mit Zeilenumbrüchen und Leerzeichen zur besseren Lesbarkeit / Erklärung:

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  }

Erläuterung

Line 01: p[][]enthält die Anzahl der Zeichen, die auf ein anderes folgen.

Line 02: XEnthält die Quelle des Programms, mit der escape-Zeichen gesetzt wurden %c%s%c.

Line 03: YEnthält die Literalquelle des Programms. c, j, *aSind Zählvariablen.

Line 05: Stellt ein Y, dass die Quine enthalten ist.

Line 06: Zähle Buchstabenvorkommen in p[][].

Line 07: Den aktuellen Status drucken.

Line 08: Finde das nächste Zeichen zufällig, proportional zu den Zählimpulsen in p[][] .

Beispielausgabe:

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}


quelle
1
Können Sie eine Version ohne Zeilenumbrüche und Leerzeichen hinzufügen, um die Anzahl der Bytes zu überprüfen?
Steven H.
1
Ja, ich habe die einzeilige Version oben hinzugefügt.
3

Ruby, 152 Bytes

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

Beispielausgabe:

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

oder

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 verwenden die Zeichenfolgenformatierung über "s%s"und führen die Markov-Verkettung durch, indem alle zweistelligen Slices genommen, gemischt und in ein Hash-Wörterbuch umgewandelt werden, wobei bei doppelten Schlüsseln das letzte Erscheinungsbild den Wert definiert. Um zu vermeiden, dass zu Beginn zusätzliche Logik hinzugefügt wird, verfolge ich das zuletzt ausgegebene Zeichen mit $/, das automatisch zu einer neuen Zeile initialisiert wird, und stelle sicher, dass im Code immer nach den neuen Zeilen 0dasselbe Zeichen folgt , mit dem der Code beginnt. Zum Schluss manipuliere ich den Quellcode so, dass es nur einen gibt, !sodass wir immer nach dem Knall enden und <<33ihn ohne das Literal hinzufügen. Dies könnte durch die Verwendung eines nicht druckbaren einstelligen Zeichens anstelle von ASCII 33 weiter verbessert werden, aber das schien zu ärgerlich.

Histokrat
quelle
4
p<<<<<33Der Super-Super-Super-Concat-Operator? ;-)
ETHproductions
3
Das ist der Operator "waaaay less than".
mbomb007
2
Ich liebe die Wörter, die dies erzeugt! Die Tatsache, dass das erste Beispiel so besorgt ist, wenn das Objekt Has(s).ears(2)mich zum Lachen bringt!
Dom Hastings
2

Rust, 564 Bytes (nicht konkurrenzfähig)

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

Da ich für eine andere Frage bereits ein hübsches Rust-Quine geschrieben hatte, dachte ich, ich würde es dafür anpassen, da es einfach genug schien. Obwohl das Original klein war, habe ich nur sehr wenig versucht, die Größe zu minimieren. Hier ist eine erweiterte Version, um zu erklären, was los ist:

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

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

Beispielausgabe 2:

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

Python 2, 211 Bytes

Gibt das Ergebnis an aus 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

Probieren Sie es online aus

Beispielausgabe:

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

Kurze Erklärung:

  • Dieses Programm verwendet das s='s=%r;print s%%s';print s%sQuine-Format. Ich erstelle eine Zeichenfolges , der das gesamte Programm enthält.
  • Die Saite X enthält die Prozedur, die rekursiv ausgeführt werden soll.
  • Die Prozedur erstellt die Ausgabezeichenfolge o, auf die gedruckt wirdstderr wenn das Ende der Markov-Kette erreicht ist.
  • Das Ende der Kette wird durch die Zeichenfolge $$mit zwei Zeichen dargestellt, sodass das Programm für alle Zeichenfolgen funktioniert. Ich hätte einen Charakter nicht in meinem Programm mögen chr(0), aber ich denke, das ist länger.
  • Das Zeichen, das bei jeder Ausführung ausgewählt wird c, owird eingefügt und (zusammen mit ) mit dem ersten Zeichen des Programms initialisiert.
  • Die Liste der Zeichen, die auf jedes Vorkommen der Auswahl cin der Zeichenfolge folgen t(die Variable, die den Quine des Quellcodes enthält) q, wird für die nächste Auswahl von ausgewählt c.
mbomb007
quelle
1

PHP, 144 135 130 120 272 220 212 Bytes

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

Oder zur besseren Lesbarkeit formatiert:

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

Beispielausgabe:

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

und:

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

und:

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

und:

<?ph($n);

PHP-Betrug, 117

Für die Neugierigen, wenn wir betrügen, indem wir unsere eigene Quelle lesen, können wir 117 tun:

<?=$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);
Regenschirm
quelle
Willkommen auf der Seite! Leider haben wir einige Regeln, die festlegen, was für Herausforderungen wie diese als richtige Quine gilt, und leider ist das Lesen aus Ihrer eigenen Quelle verboten.
Wheat Wizard
Oh, gut, danke. Ich habe nach den Regeln gesucht. Ich muss das überarbeiten.
Umbrella