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 can
nach a c
eine Wahrscheinlichkeit von zwei Dritteln und eine Wahrscheinlichkeit von o
einem 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.
- 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)
- Sie können das Modell so ändern, dass Bytes anstelle von Zeichen verwendet werden. Ändern Sie jedoch in Regel 1 "Zeichen" in "Bytes"
- Das Programm sollte Strings zufällig mit der theoretisch erwarteten Häufigkeit ausgeben
Das ist Code-Golf , also gewinnt das kürzeste Programm!
quelle
^
und$
in Anführungszeichen? es könnte klarer sein, es aus Anführungszeichen zu entfernen oder sie in Anführungszeichen zu setzen.Antworten:
Pip , 64 Bytes
Das hat Spaß gemacht.
<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:Das heißt:
Y
ank (Speichern alsy
) eine Zeichenfolge mit"V Y".RPy
und eV
.RPy
Nimmt den Repräsentanteny
, dem wir die wörtliche Zeichenfolge voranstellenV 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 zut
. Weist im eval'd-Codem:"..."
eine Code-Zeichenfolge zum
, die wir am Ende mit auswertenVm
.ST["t:V Y"RPy";Vm"C9]
erstellt eine Liste mitund 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 derV
Operator den Wert zurück und wird diesem zugewiesent
.Also, nach der Auswertung und Zuordnung,
t
gleich der vollständige Code undm
enthältJetzt
Vm
wertet das als Code aus. Lassen Sie uns zusammenfassen, was passiert.Ein paar Notizen:
xxy
nurxx
und nichtxy
in den Übereinstimmungen zurückgegeben. Glücklicherweise enthält dieser Code jedoch keine doppelten Zeichen, sodass es keine Rolle spielt.quelle
JavaScript,
217.215ByteBeachten Sie, dass dies verwendet
uneval
, was nur von Firefox unterstützt wird. Probeläufe: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:
Sehr, sehr selten gibt dies syntaktisch gültiges JS aus:
Mein Favorit der erstellten Funktionsnamen ist
.splendom()
(split
+length
+random
)quelle
a.splerength.r()
, was gültig sein könnte;)Perl, 103 Bytes
Basierend auf der Standard-Quine und meiner Antwort auf diese Frage :
Beispielausgabe
Ähnlich wie bei der anderen Frage generieren einige Ergebnisse gültiges Perl:
Die Chancen sind jedoch mit ~ 2% etwas geringer.
quelle
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).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:
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:
In Assembler-Code konvertiert sieht das Programm so aus:
quelle
C 306
328585611615623673707BytesQuellcode:
Mit Zeilenumbrüchen und Leerzeichen zur besseren Lesbarkeit / Erklärung:
Erläuterung
Line 01
:p[][]
enthält die Anzahl der Zeichen, die auf ein anderes folgen.Line 02
:X
Enthält die Quelle des Programms, mit der escape-Zeichen gesetzt wurden%c%s%c
.Line 03
:Y
Enthält die Literalquelle des Programms.c
,j
,*a
Sind Zählvariablen.Line 05
: Stellt einY
, dass die Quine enthalten ist.Line 06
: Zähle Buchstabenvorkommen inp[][]
.Line 07
: Den aktuellen Status drucken.Line 08
: Finde das nächste Zeichen zufällig, proportional zu den Zählimpulsen inp[][]
.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
Ruby, 152 Bytes
Beispielausgabe:
oder
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 Zeilen0
dasselbe 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<<33
ihn 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.quelle
p<<<<<33
Der Super-Super-Super-Concat-Operator? ;-)Has(s).ears(2)
mich zum Lachen bringt!Rust, 564 Bytes (nicht konkurrenzfähig)
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:
Beispielausgabe 1:
Beispielausgabe 2:
quelle
Python 2, 211 Bytes
Gibt das Ergebnis an aus
stderr
.Probieren Sie es online aus
Beispielausgabe:
Kurze Erklärung:
s='s=%r;print s%%s';print s%s
Quine-Format. Ich erstelle eine Zeichenfolges
, der das gesamte Programm enthält.X
enthält die Prozedur, die rekursiv ausgeführt werden soll.o
, auf die gedruckt wirdstderr
wenn das Ende der Markov-Kette erreicht ist.$$
mit zwei Zeichen dargestellt, sodass das Programm für alle Zeichenfolgen funktioniert. Ich hätte einen Charakter nicht in meinem Programm mögenchr(0)
, aber ich denke, das ist länger.c
,o
wird eingefügt und (zusammen mit ) mit dem ersten Zeichen des Programms initialisiert.c
in der Zeichenfolge folgent
(die Variable, die den Quine des Quellcodes enthält)q
, wird für die nächste Auswahl von ausgewähltc
.quelle
PHP,
144135130120272220212 BytesOder zur besseren Lesbarkeit formatiert:
Beispielausgabe:
und:
und:
und:
PHP-Betrug, 117
Für die Neugierigen, wenn wir betrügen, indem wir unsere eigene Quelle lesen, können wir 117 tun:
quelle