APL (158 Zeichen, Punktzahl = 4)
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
Ich verwende hier Dyalog APL. Die Anzahl der Zyklen kann um eins erhöht werden, indem 0
am Ende des Ausdrucks und am Ende der Zeichenfolge (vor '''
) (0 gefolgt von einem Leerzeichen) hinzugefügt wird . Die Zykluslänge ist (# 0's) + 1
und die Länge des Ausdrucks ist 150 + 4*(cycle length))
. Angenommen, wir fügen für immer Nullen hinzu, dann ist die Punktzahl Limit[(150 + 4*n)/(n - 1), n -> Infinity] = 4
, wo n
die Zykluslänge ist.
Hier ist ein Beispiel mit Zykluslänge = 6:
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
192 Zeichen, Punktzahl = 2
'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺ ⋄ a←⊃2⌷⍺ ⋄ ⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺⋄a←⊃2⌷⍺⋄⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01
Abhängig von der Implementierung kann ein Fehler auftreten, wenn die der Zeichenfolge vorangestellte Ganzzahl zu groß ist. Theoretisch können wir jedoch einen Zyklus hinzufügen, indem wir zwei Zeichen hinzufügen - a 1
am Ende der Zeichenfolge (vor '''
) und a 1
am Ende der gesamten Zeile.
200 Zeichen, Punktzahl = 1
'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}91
Meine APL-Implementierung verfügt standardmäßig nicht über Ganzzahlen mit unbegrenzter Genauigkeit. Daher wird die Ganzzahl in einen Gleitkommawert konvertiert, wenn sie zu groß wird, was zu einer falschen Ausgabe führt. Das ist also das heikelste, aber theoretisch (entweder von Hand oder mit einem anderen APL-Interpreter) sollte es eine Punktzahl von 1 haben. Fügen Sie einfach 1
am Ende des Ausdrucks ein hinzu, und Sie erhalten einen weiteren Zyklus.
Übersicht (mit kürzerem Quine)
Ich werde einen Überblick über die erste Version geben, da ich denke, dass es wahrscheinlich am einfachsten ist, sie zu verstehen. Bevor wir diese Version jedoch in Angriff nehmen, betrachten wir eine einfache Quine in APL :
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
Ich habe festgestellt, dass eine der besten Möglichkeiten zum Verständnis einiger APL-Ausdrücke darin besteht, die Ausgabe in der Kaskade der Operatoren / Funktionen zu betrachten. Alle Operatoren und Funktionen in APL sind rechtsassoziativ und haben die gleiche Priorität. Hier also von rechts nach links:
'''1⌽22⍴11⍴'''
: Dies ist nur ein String-Literal (eine Liste von Zeichen). ''
ist die APL-Methode, um einfache Anführungszeichen zu umgehen. Ausgang: '1⌽22⍴11⍴'
.
11⍴'''1⌽22⍴11⍴'''
: Hier formen wir ⍴
den String um ( ), damit er lang ist 11
. Da die Länge der Zeichenfolge unter 11 liegt, wird sie wiederholt (dh sie 5⍴'abc'
würde nachgeben 'abcab'
). Ausgang: '1⌽22⍴11⍴''
. Also haben wir jetzt zwei Anführungszeichen am Ende - wir kommen irgendwohin!
22⍴11⍴'''1⌽22⍴11⍴'''
: In ähnlicher Weise gestalten wir jetzt unsere vorherige Ausgabe so um, dass sie lang ist 22
. Ausgang: '1⌽22⍴11⍴'''1⌽22⍴11⍴''
. Wir sind fast da - wir müssen nur das erste einfache Anführungszeichen ans Ende setzen.
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
: Hier drehen wir ( ⌽
) die Liste der Zeichen um 1
. Dadurch wird das erste Zeichen der Zeichenfolge an das Ende verschoben. Als weiteres Beispiel wird 2⌽'abcdef'
zurückgegeben 'cdefab'
. Ausgang: 1⌽22⍴11⍴'''1⌽22⍴11⍴'''
.
Das rotierende Quin
Diese kurze Quine ist die Hauptgrundlage für unsere rotierende Quine. Schauen wir uns in diesem Sinne unsere Quine an:
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
{ ... }
definiert eine unbenannte Funktion, in der wir die Arbeit erledigen werden. Beachten Sie, dass Funktionen in APL ein rechtes Argument (bezeichnet mit ⍵
) und ein optionales linkes Argument (bezeichnet mit ⍺
(think infix)) enthalten. Wir möchten mit dieser Funktion sowohl unseren Quine-String als auch etwas füttern, das uns dabei hilft, eine beliebige Anzahl von Zyklen zu erstellen. Um es uns (und allen, die Zyklen hinzufügen möchten) einfacher zu machen, machen wir den Quine-String zum linken Argument. Das richtige Argument ist also, wo wir unsere Liste der Zyklen ablegen. Zwei oder mehr durch ein Leerzeichen getrennte Elemente erstellen eine Liste. In diesem Beispiel haben wir also eine Liste mit zwei Elementen, bestehend aus a 1
und a 0
.
Wir können sehen, dass die Funktion der Quine von früher ähnelt. Wir haben die gleiche ...⌽...⍴...⍴...
Form von vor. Das ist gut so - wir verstehen zumindest so viel! Lassen Sie sich tiefer in die Ellipsen, beginnend mit allem , was nach dem letzten ⍴
: ⊃,/(~^/¨⍺=0)/⍺
.
- Wie Sie anhand des obigen Beispiels sehen können, stellen wir der Zeichenfolge rechts die Nullen voran und fügen bei jeder Iteration eine hinzu. aber das interessiert uns im Moment nicht. Wir wollen nur die Zeichenfolge!
- Betrachten Sie zunächst, was in Klammern steht. (Sie gruppieren sich übrigens wie in den meisten anderen Sprachen.)
⍺=0
In diesem Fall wird eine Liste mit der gleichen Form wie zurückgegeben ⍺
, wobei jedes Element in ⍺
durch ein, 1
wenn es gleich ist 0
, und ein, wenn nicht, ersetzt wird 0
. Dies wird rekursiv durchgeführt. Wenn wir also eine Liste mit einer Liste mit Zeichen haben, werden die einzelnen Zeichen gegen 0 getestet und Sie erhalten eine Liste mit einer Liste mit Binärwerten zurück.
- Wenn es
⍺
sich also nur um unsere Zeichenfolge handelt, erhalten wir eine Liste mit Nullen zurück. Andernfalls sind unserem linken Argument einige Nullen vorangestellt (z. B. 0 0 0 'quinestring'
), sodass es sich um eine Liste handelt, die aus Nullen und einer anderen Liste, unserer Zeichenfolge, besteht. Dann sieht unsere Ausgabe so aus 1 1 1 <sub-list of zeros>
.
^/¨⍺=0
: Wir wenden die abgeleitete Funktion ^/
, die ( /
) unter Verwendung der logischen AND ( ^
) - Funktion reduziert , auf jedes ( ¨
) - Element von an ⍺=0
. Dies soll die Unterliste der Nullen abflachen, so dass wir den Quine-String als einen Binärwert betrachten können. In Anbetracht des vorherigen Beispiels wäre die Ausgabe 1 1 1 0
.
~
: Wir binären NICHT jeden der Werte von vor (z 0 0 0 1
. B. Rückkehr ).
(~^/¨⍺=0)/⍺
: Für jedes Element in ⍺
replizieren wir /
es so oft, wie das entsprechende Element im linken Argument es angibt. Dies eliminiert alle Nullen und lässt uns nur mit unserer Quine-Saite zurück.
⊃,/
Es sind einige Formalitäten erforderlich, um sicherzustellen, dass wir eine reduzierte Liste von Zeichen erhalten, indem wir das Ergebnis mit der Verkettungsfunktion ( ,
) reduzieren . Wenn die Eingabe bereits eine abgeflachte Liste ist (dh das linke Argument für unsere Hauptfunktion ist nur die Zeichenfolge), erhalten wir eine Liste mit 1 Elementen, die diese Liste enthält. In dem anderen Fall, wenn wir eine Liste haben, die aus einer Unterliste für den String besteht, erhalten wir dasselbe zurück (eine Liste mit einer Unterliste). Wir entpacken dann this ( ⊃
) und geben uns nur das erste Element der Liste (dh die Unterliste der Zeichen). Dies mag unnötig erscheinen, aber sonst würden wir versuchen, eine Liste mit 1 Elementen umzugestalten!
Als nächstes betrachten wir die Länge, die für die erste Umformung in Klammern angegeben wurde:
⍺,⍵
: Wir verketten das richtige Argument mit dem ersten Argument
⊃,/⍺,⍵
: Wie zuvor - Reduzieren Sie die Liste.
+/0=⊃,/⍺,⍵
: Addieren Sie die Anzahl der Nullen in der Liste, indem Sie ( /
) mit der +
Funktion addition ( ) reduzieren .
2×+/0=⊃,/⍺,⍵
: Multipliziere diese Zahl mit zwei.
z←2×+/0=⊃,/⍺,⍵
: Zuweisen ( ←
) das Ergebnis in einer Variablen z
. Um es noch einmal zusammenzufassen:z
sich jetzt die doppelte Anzahl von Nullen sowohl im linken als auch im rechten Argument gefunden wird.
77+z←2×+/0=⊃,/⍺,⍵
: Wir fügen dann hinzu 77
für die Zeichen in der Quine-Zeichenfolge hinzu und ignorieren alles nach dem Leerzeichen 1
. Wie im ersten Quine-Beispiel addieren wir 1 zur Länge des Strings, um ein weiteres einfaches Anführungszeichen zu erhalten.
- Die Ausgabe dieser Umformung in diesem Beispiel lautet:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
Das Argument für die folgende Umformung ist einfach und spiegelt die kurze Quine wider (2-fache Länge für die erste Umformung). Unsere Ausgabe ist jetzt:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
Nun zum letzten Schritt, in dem wir berechnen, um wie viel die Ausgabezeichenfolge gedreht werden soll:
- Wie Sie an der vorherigen Ausgabe sehen können, möchten wir sie zurückdrehen (um einen negativen Betrag), um die beiden letzten Anführungszeichen an den Anfang zu bringen. Weil wir eine wollen
0
(und ein anderes) Leerzeichen an den Anfang bewegt, möchten wir es um weitere 3 Zeichen zurückdrehen.
+/+/¨⍺=0
: Addiere die Anzahl der Nullen im linken Argument. Die erste (von rechts) +/¨
summiert die Anzahl der Elemente (dh eine Unterliste oder nur eine Ganzzahl) und die zweite +/
ergibt die Summe dieser resultierenden Liste.
5+2×+/+/¨⍺=0
: Multiplizieren Sie mit zwei (um auch die Leerzeichen zu drehen) und addieren Sie 5 (das Ergebnis, das wir zuvor gefunden haben).
- Nun subtrahieren wir den vorherigen Wert vom linken Argument,
-
um den Fall zu behandeln, wenn wir das Ende unseres Zyklus erreicht haben:
(3+z)×^/⍵
: UND alle Elemente im richtigen Argument zusammen, um zu sehen, ob wir unser Ende erreicht haben ( 1
), und multiplizieren Sie das mit 3+z
.
Und wir sind fertig!