Golf du ein Quine für großes Wohl!


204

Spielen Sie in der Sprache Ihrer Wahl eine Quine .

Ein Quine ist ein nicht leeres Computerprogramm, das keine Eingaben vornimmt und als einzige Ausgabe eine Kopie seines eigenen Quellcodes erstellt.

Kein Schummeln - das bedeutet, dass Sie die Quelldatei nicht einfach lesen und ausdrucken können. In vielen Sprachen ist eine leere Datei auch eine Quine: Auch das wird nicht als legitime Quine betrachtet.

Keine Fehlerquines - Für Fehlerquines gibt es bereits eine separate Herausforderung .

Punkte für:

  • Kleinster Code (in Bytes)
  • Am meisten verschleierte / undurchsichtige Lösung
  • Verwenden esoterischer / obskurer Sprachen
  • Erfolgreiche Verwendung von Sprachen, in denen schwer Golf zu spielen ist

Das folgende Stapel-Snippet kann verwendet werden, um einen schnellen Überblick über die aktuelle Punktzahl in jeder Sprache zu erhalten und um zu wissen, welche Sprachen Antworten haben und welches Ziel Sie schlagen müssen:


4
Meinst du nicht "Golf du ein Quine für mehr Gutes!"?
Mateen Ulhaq

50
@muntoo es ist ein Stück über "Learn you a Haskell for Great Good".
Rafe Kettler

Antworten:


106

Hexagony , Seitenlänge 17 16, 816 705 Bytes

180963109168843880558244491673953327577233938129339173058720504081484022549811402058271303887670710274969455065557883702369807148960608553223879503892017157337685576056512546932243594316638247597075423507937943819812664454190530214807032600083287129465751195839469777849740055584043374711363571711078781297231590606019313065042667406784753422844".".>.@.#.#.#.#.#.#.#.>.(...........................<.".......".".>./.4.Q.;.+.<.#.>...........................<.".....".".>.#.#.>.N.2.'.\.>.............=.=......._.<.".....".".>.>.;.'.=.:.\.>.......................<."...".".>.\.'.%.'.<.#.>..............._.....<."...".".>.#.#.>.<.#.>...............=.=.<.".".".>.#.\.'.R./.>.................<.".!.........../.>.

Probieren Sie es online!

So sieht es ungefaltet aus:

                1 8 0 9 6 3 1 0 9 1 6 8 8 4 3 8
               8 0 5 5 8 2 4 4 4 9 1 6 7 3 9 5 3
              3 2 7 5 7 7 2 3 3 9 3 8 1 2 9 3 3 9
             1 7 3 0 5 8 7 2 0 5 0 4 0 8 1 4 8 4 0
            2 2 5 4 9 8 1 1 4 0 2 0 5 8 2 7 1 3 0 3
           8 8 7 6 7 0 7 1 0 2 7 4 9 6 9 4 5 5 0 6 5
          5 5 7 8 8 3 7 0 2 3 6 9 8 0 7 1 4 8 9 6 0 6
         0 8 5 5 3 2 2 3 8 7 9 5 0 3 8 9 2 0 1 7 1 5 7
        3 3 7 6 8 5 5 7 6 0 5 6 5 1 2 5 4 6 9 3 2 2 4 3
       5 9 4 3 1 6 6 3 8 2 4 7 5 9 7 0 7 5 4 2 3 5 0 7 9
      3 7 9 4 3 8 1 9 8 1 2 6 6 4 4 5 4 1 9 0 5 3 0 2 1 4
     8 0 7 0 3 2 6 0 0 0 8 3 2 8 7 1 2 9 4 6 5 7 5 1 1 9 5
    8 3 9 4 6 9 7 7 7 8 4 9 7 4 0 0 5 5 5 8 4 0 4 3 3 7 4 7
   1 1 3 6 3 5 7 1 7 1 1 0 7 8 7 8 1 2 9 7 2 3 1 5 9 0 6 0 6
  0 1 9 3 1 3 0 6 5 0 4 2 6 6 7 4 0 6 7 8 4 7 5 3 4 2 2 8 4 4
 " . " . > . @ . # . # . # . # . # . # . # . > . ( . . . . . .
  . . . . . . . . . . . . . . . . . . . . . < . " . . . . . .
   . " . " . > . / . 4 . Q . ; . + . < . # . > . . . . . . .
    . . . . . . . . . . . . . . . . . . . . < . " . . . . .
     " . " . > . # . # . > . N . 2 . ' . \ . > . . . . . .
      . . . . . . . = . = . . . . . . . _ . < . " . . . .
       . " . " . > . > . ; . ' . = . : . \ . > . . . . .
        . . . . . . . . . . . . . . . . . . < . " . . .
         " . " . > . \ . ' . % . ' . < . # . > . . . .
          . . . . . . . . . . . _ . . . . . < . " . .
           . " . " . > . # . # . > . < . # . > . . .
            . . . . . . . . . . . . = . = . < . " .
             " . " . > . # . \ . ' . R . / . > . .
              . . . . . . . . . . . . . . . < . "
               . ! . . . . . . . . . . . / . > .
                . . . . . . . . . . . . . . . .

Ach ja, das war ganz die emotionale Achterbahnfahrt ... Ich hielt die wievielten Mal ich zwischen switched „Haha, das ist Wahnsinn“ und „warten, wenn ich es tue dies sollte es eigentlich ziemlich machbar sein“. Die Einschränkungen, die Hexagony durch seine Layoutregeln für den Code auferlegt hat, waren ... schwerwiegend.

Es könnte möglich sein, die Seitenlänge um 1 oder 2 zu reduzieren, ohne den allgemeinen Ansatz zu ändern, aber es wird schwierig (nur die Zellen mit #sind derzeit unbenutzt und für den Decoder verfügbar). Im Moment habe ich auch absolut keine Ideen mehr, wie man effizienter vorgehen könnte, aber ich bin mir sicher, dass es eine gibt. In den nächsten Tagen werde ich darüber nachdenken und vielleicht versuchen, nebenbei Golf zu spielen, bevor ich eine Erklärung und alles hinzufüge.

Zumindest habe ich bewiesen, dass es möglich ist ...

Einige CJam-Skripte für meine eigene zukünftige Referenz:


51
Lieber Peter, was ist das?
Conor O'Brien

2
Wie lange hat das gedauert?
Adnan

3
@AandN Ich habe seit gestern ab und zu mit Konzepten für ein allgemeines "Template" rumgespielt (das beinhaltete keine eigentlichen Tests ... ich habe nur ein paar Dinge in ein 7x7-Raster geschrieben und herausgefunden, ob es funktionieren könnte. Ich habe wahrscheinlich ein halbes Dutzend Ansätze bereits dort verworfen. Die eigentliche Codierung hat dann heute Abend gedauert ... vielleicht 3 Stunden, würde ich sagen.
Martin Ender

10
Worte können nicht erklären, wie erstaunt ich bin, wenn ich das Schritt für Schritt mit Esoteric IDE in Aktion sehe ... Für wen das verständlich sein soll, codiert dieses Hexagon den "Decoder" -Teil in eine Ganzzahl, die mit !und dann mit einem gedruckt wird Spiegeln /Sie die zweitletzte Zeile und geben Sie den Decoder-Code ein, um das Quine zu vervollständigen. Dies nutzt auf wundersame Weise <und >liest die mehrzeilige, sehr große Ganzzahl und baut den Speicherbereich für den Decoder auf. Ich würde wirklich gerne wissen, welche "Dutzende von Ansätzen" in Betracht gezogen werden?
Sunny Pun

3
Erläuterung? ---
MD XF

77

MySQL, 167 Zeichen

SELECT REPLACE(@v:='SELECT REPLACE(@v:=\'2\',1+1,REPLACE(REPLACE(@v,\'\\\\\',\'\\\\\\\\\'),\'\\\'\',\'\\\\\\\'\'));',1+1,REPLACE(REPLACE(@v,'\\','\\\\'),'\'','\\\''));

Stimmt. :-)

Ich habe das wirklich selbst geschrieben. Es wurde ursprünglich auf meiner Website veröffentlicht .


72

GolfScript, 2 Bytes

1

(Beachten Sie den Zeilenvorschub) Dies drückt die Nummer 1 auf den Stapel. Am Ende des Programms druckt GolfScript alle Elemente im Stapel aus (ohne Leerzeichen dazwischen) und druckt dann eine neue Zeile.

Dies ist eine echte Quine (wie in der Frage aufgeführt), da sie den Code tatsächlich ausführt. Es wird nicht nur "die Quelldatei gelesen und gedruckt" (im Gegensatz zur PHP-Übermittlung).


Ein weiteres Beispiel ist das folgende GolfScript-Programm zum Drucken 12345678:

9,(;
  1. 9: 9 zum Stapel schieben
  2. ,: verbrauchen Sie die 9 als Argument, schieben Sie das Array [0 1 2 3 4 5 6 7 8]auf den Stapel
  3. (: Verbrauchen Sie das Array als Argument, verschieben Sie das Array [1 2 3 4 5 6 7 8]und das Element 0in den Stapel
  4. ;: Lege den obersten Gegenstand des Stapels ab

Der Stack enthält nun das Array [1 2 3 4 5 6 7 8]. Dies wird in die Standardausgabe geschrieben, ohne Leerzeichen zwischen den Elementen, gefolgt von einer neuen Zeile.


18
Oder PowerShell oder PHP :-)
Joey

6
Sie sind nicht in die Vergangenheit gereist und haben dem Erfinder die Idee gegeben, GolfScript zu erfinden, oder?
Mateen Ulhaq

78
Technisch gesehen 1ist es in GolfScript kein Quine: Es wird ausgegeben 1\n, wobei \neine Newline bezeichnet wird. Das Zwei-Zeichen-Programm 1\n ist jedoch ein Quine.
Ilmari Karonen

17
Das Ein-Zeichen-Programm ist \nwahrscheinlich auch?
Lynn

10
@Pseudonym a quine ist buchstäblich ein Programm, das seine eigene Quelle druckt. Ich glaube nicht, dass es irgendwelche willkürlichen Beschränkungen für "Struktur" gibt.
Hugo Zink

71

Brain-Flak , 9.8e580 1.3e562 9.3e516 12818 11024 4452 4332 4240 4200 4180 3852 3656 3616 3540 2485 + 3 = 2488 Bytes

Passt jetzt in das beobachtbare Universum!

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()())([[]]){({}()<(([{}]())<{({}())<>(((((()()()()()){}){}){}())[()])<>{({}())<>{}({}(((()()()){}())){}{})<>{({}())<>({}(((()()()()()){})){}{}())<>{{}<>({}(((()()()()){}){}){})(<>)}}<>(({})[()()])<>}}{}<>({}(<()>)<><{({}<>)<>}<>>){({}<>)<>}{}(<>)<>{({}<>)<>}{}(((((((()()()()()){}){}){}))()))>){({}()<((({}[()])()))>)}{}<>{({}<>)<>}{}>)}{}<>{({}<>)<>}<>

Probieren Sie es online!


Erläuterung

Diese Quine funktioniert wie die meisten Quines in esoterischen Sprachen. Es besteht aus zwei Teilen, einem Encoder und einem Decoder. Der Encoder steht am Anfang in Klammern und der Decoder ist am Ende der komplexere Teil.

Eine naive Art, das Programm zu codieren, besteht darin, den ASCII-Wert jedes Zeichens im Decoder auf den Stapel zu legen. Dies ist keine sehr gute Idee, da Brain-Flak nur 8 Zeichen ( ()<>[]{}) verwendet, sodass Sie am Ende ziemlich viele Bytes bezahlen, um sehr wenig Informationen zu codieren. Eine klügere Idee, und die bisher verwendete ist es, jede der 8 geschweiften Klammern einer viel kleineren Zahl (1-8) zuzuweisen und diese mit unserem Decoder in die ASCII-Werte umzuwandeln. Das ist nett, weil es nicht mehr als 18 Bytes kostet, ein Zeichen zu codieren, im Gegensatz zum vorherigen 252.

Dieses Programm funktioniert jedoch nicht. Es beruht auf der Tatsache, dass alle Brain-Flak-Programme so aufeinander abgestimmt sind, dass sie die 8 Klammern mit den Zahlen bis 5 codieren. Es codiert sie wie folgt.

(       -> 2
<       -> 3
[       -> 4
{       -> 5
),>,],} -> 1

Allen geschweiften Klammern wird 1 zugewiesen, da wir mithilfe des Kontexts bestimmen können, welche von ihnen in einem bestimmten Szenario verwendet werden müssen. Das klingt nach einer entmutigenden Aufgabe für ein Brain-Flak-Programm, ist es aber nicht. Nehmen Sie zum Beispiel die folgenden Kodierungen, bei denen die offenen Klammern dekodiert und die schließenden Klammern durch ein ersetzt werden .:

(.
((..
<([.{...

Hoffentlich können Sie sehen , dass der Algorithmus ziemlich einfach ist, lesen wir links nach rechts, jedes Mal , wenn wir stoßen auf eine offene Klammer wir die enge Klammer zu einer gedachten Stapel schieben und wenn wir begegnen ein .Pop wir den Top-Wert und legen Sie sie anstelle der .. Diese neue Kodierung spart uns eine enorme Anzahl von Bytes im Kodierer, während wir nur eine Handvoll Bytes im Dekodierer verlieren.

Low Level Erklärung

In Arbeit


25
Ich denke, Sie gewinnen für die längste Lösung einer Code-Golf-Herausforderung ...
Mego

18
Habe gerade den größten Einzelgolf in der Geschichte von PPCG Nope gemacht. 9.8e580 ist immer noch beeindruckend.
Dennis

19
+1 für die Anpassung an das beobachtbare Universum. Außerdem sollte mit TIO Nexus der Permalink in die Antwort passen. tio.run/nexus/…
Dennis

3
... sehr großes Golf ...
Destructible Lemon

3
Ich denke, Sie gewinnen für die meisten abgeschnittenen Bytes
Christopher

68

Prelude , 5157 4514 2348 1761 1537 664 569 535 423 241 214 184 178 175 169 148 142 136 133 Bytes

Danke an Sp3000 für das Speichern von 3 Bytes.

Das ist ziemlich lang ... (okay, es ist immer noch lang ... zumindest schlägt es bei dieser Herausforderung die kürzeste bekannte C # -Qualität von Brainfuck ), aber es ist die erste Quine, die ich selbst entdeckt habe (meine Einsendungen von Lua und Julia sind wirklich nur Übersetzungen von Standard Quine Techniken in anderen Sprachen) und soweit ich weiß, hat noch niemand eine Quine in Prelude geschrieben, also bin ich ziemlich stolz darauf. :)

7( -^^^2+8+2-!( 6+ !
  ((#^#(1- )#)8(1-)8)#)4337435843475142584337433447514237963742423434123534455634423547524558455296969647344257)

Diese große Anzahl von Ziffern ist nur eine Kodierung des Kerncodes, weshalb der Quine so lang ist.

Die Ziffern, die das Quine codieren, wurden mit diesem CJam-Skript generiert .

Dies erfordert einen standardkonformen Interpreter, der Zeichen druckt (wobei die Werte als Zeichencodes verwendet werden). Wenn Sie also den Python-Interpreter verwenden, müssen Sie festlegen NUMERIC_OUTPUT = False.

Erläuterung

Zunächst ein paar Worte zum Prelude: Jede Zeile im Prelude ist eine eigene "Stimme", die ihren eigenen Stack manipuliert. Diese Stapel werden auf eine unendliche Anzahl von Nullen initialisiert. Das Programm wird Spalte für Spalte ausgeführt, wobei alle Befehle in der Spalte auf der Grundlage der vorherigen Stapelzustände "gleichzeitig" ausgeführt werden. Die Ziffern werden einzeln auf den Stapel geschoben, so 42dass zuerst a 4und dann a gedrückt werden 2. Es gibt keine Möglichkeit, größere Zahlen direkt zu übertragen. Sie müssen sie addieren. Mit vund können Werte aus benachbarten Stapeln kopiert werden ^. Brainfuck-artige Loops können mit runden Klammern eingefügt werden. Weitere Informationen finden Sie unter dem Link in der Überschrift.

Hier ist die Grundidee des Quines: Zuerst schieben wir eine Menge Ziffern auf den Stapel, die den Kern des Quines kodieren. Der Kern nimmt dann diese Ziffern, decodiert sie, um sie selbst zu drucken, und druckt dann die Ziffern, wie sie im Code (und dem nachfolgenden Code )) erscheinen.

Dies ist etwas kompliziert durch die Tatsache, dass ich den Kern über mehrere Zeilen aufteilen musste. Ursprünglich hatte ich die Kodierung am Anfang, musste dann aber die anderen Zeilen mit der gleichen Anzahl von Leerzeichen auffüllen. Aus diesem Grund waren die anfänglichen Punktzahlen alle so groß. Jetzt habe ich die Codierung am Ende eingefügt, aber das bedeutet, dass ich zuerst den Kern überspringen, dann die Ziffern eingeben und zum Anfang zurückspringen und den Druck ausführen muss.

Die Kodierung

Da der Code nur zwei Stimmen hat, und und Nachbarschaft ist zyklisch ^und vsind synonym. Das ist gut so, weil ves mit Abstand den größten Zeichencode hat. Wenn Sie ihn also immer verwenden, wird ^die Codierung einfacher. Jetzt liegen alle Zeichencodes im Bereich von 10 bis einschließlich 94. Das heißt, ich kann jedes Zeichen mit genau zwei Dezimalstellen codieren. Es gibt jedoch ein Problem: Einige Zeichen, insbesondere der Zeilenvorschub, haben eine Null in ihrer Dezimaldarstellung. Dies ist ein Problem, da Nullen nicht leicht vom unteren Ende des Stapels zu unterscheiden sind. Zum Glück gibt es eine einfache Lösung: Wir versetzen die Zeichencodes um 2, sodass wir einen Bereich von 12 bis einschließlich 96 haben, der immer noch bequem in zwei Dezimalstellen passt. Nun von allen Zeichen, die im Prelude-Programm erscheinen können,0hat eine 0 in seiner Darstellung (50), aber wir brauchen 0überhaupt nicht. Das ist also die Kodierung, die ich verwende, indem ich jede Ziffer einzeln drücke.

Da wir jedoch mit einem Stapel arbeiten, werden die Darstellungen umgekehrt verschoben. Wenn Sie sich also das Ende der Kodierung ansehen:

...9647344257

In Paare aufteilen und umkehren, dann zwei subtrahieren und dann die Zeichencodes nachschlagen:

57 42 34 47 96
55 40 32 45 94
 7  (     -  ^

Wo 32ist entspricht Leerzeichen. Der Core führt genau diese Transformation durch und druckt dann die Zeichen.

Der Kern

Schauen wir uns also an, wie diese Zahlen tatsächlich verarbeitet werden. Zunächst ist zu beachten, dass übereinstimmende Klammern in Prelude nicht in derselben Zeile stehen müssen. Es kann nur eine Klammer pro Spalte geben, daher gibt es keine Mehrdeutigkeit, in der Klammern zusammengehören. Insbesondere ist die vertikale Position der schließenden Klammer immer irrelevant - der Stapel, der überprüft wird, ob die Schleife endet (oder vollständig übersprungen wird), ist immer derjenige, der die hat (.

Wir wollen den Code genau zweimal ausführen - beim ersten Mal überspringen wir den Kern und drücken alle Zahlen am Ende, beim zweiten Mal führen wir den Kern aus. Tatsächlich werden wir, nachdem wir den Core ausgeführt haben, alle diese Zahlen erneut übertragen, aber da die Schleife danach endet, ist dies irrelevant. Dies ergibt das folgende Skelett:

7(
  (                   )43... encoding ...57)

Zuerst drücken wir eine 7auf die erste Stimme - wenn wir das nicht tun, treten wir niemals in die Schleife ein (für das Skelett ist es nur wichtig, dass dies nicht Null ist ... warum es spezifisch ist, werden 7wir später sehen) . Dann betreten wir die Hauptschleife. Jetzt enthält die zweite Stimme einen weiteren Loop. Beim ersten Durchlauf wird diese Schleife übersprungen, da der zweite Stapel leer ist / nur Nullen enthält. Also springen wir direkt zur Kodierung und schieben alle diese Ziffern auf den Stapel. Das, was 7wir auf den ersten Stapel geschoben haben, ist noch da, also wiederholt sich die Schleife.

Dieses Mal gibt es auch einen 7auf dem zweiten Stapel, also geben wir eine Schleife auf der zweiten Stimme ein. Die Schleife der zweiten Stimme ist so ausgelegt, dass der Stapel am Ende wieder leer ist und nur einmal ausgeführt wird. Es wird auch den ersten Stapel erschöpfen ... Wenn wir also die Schleife mit der zweiten Stimme verlassen, drücken wir erneut alle Ziffern, aber jetzt wurde 7der erste Stapel verworfen, sodass die Hauptschleife endet und das Programm endet.

Als nächstes schauen wir uns die erste Schleife im eigentlichen Kern an. Es ist sehr interessant, Dinge gleichzeitig mit einem (oder zu tun ). Ich habe den Schleifenkörper hier markiert mit =:

-^^^2+8+2-!
(#^#(1- )#)
 ==========

Dies bedeutet, dass die Spalte, die enthält, (nicht als Teil der Schleife betrachtet wird (die Zeichen dort werden nur einmal ausgeführt, und selbst wenn die Schleife übersprungen wird). Die Spalte, die das enthält, ) ist Teil der Schleife und wird bei jeder Iteration einmal ausgeführt.

Also fangen wir mit einer Single an -, die 7den ersten Stack in einen -7... verwandelt , dazu später mehr. Wie für die eigentliche Schleife ...

Die Schleife wird fortgesetzt, solange der Ziffernstapel nicht geleert wurde. Es verarbeitet zwei Ziffern gleichzeitig. Der Zweck dieser Schleife besteht darin, die Codierung zu decodieren, das Zeichen auszudrucken und gleichzeitig den Ziffernstapel auf die erste Stimme zu verschieben. Also dieser Teil zuerst:

^^^
#^#

In der ersten Spalte wird die Ziffer zur ersten Stimme verschoben. In der zweiten Spalte wird die 10-stellige Zahl in die erste Stimme kopiert, während gleichzeitig die 1-stellige Zahl in die zweite Stimme zurückkopiert wird. Die dritte Spalte verschiebt diese Kopie zurück zur ersten Stimme. Das heißt, die erste Stimme hat jetzt die 1-Stelle zweimal und die 10-Stelle dazwischen. Die zweite Stimme hat nur eine weitere Kopie der 10-stelligen. Das heißt, wir können mit den Werten oben auf den Stapeln arbeiten und sicherstellen, dass auf dem ersten Stapel noch zwei Kopien für später vorhanden sind.

Nun stellen wir den Zeichencode aus den beiden Ziffern wieder her:

2+8+2-!
(1- )#

Der untere Teil ist eine kleine Schleife, die nur die 10-stellige Zahl auf Null dekrementiert. Für jede Iteration wollen wir 10 an die Spitze setzen. Denken Sie daran, dass der erste 2nicht Teil der Schleife ist. Der Loop-Body +8+2addiert also 10 (mit dem 2zuvor gedrückten) und der andere 2. Wenn wir also mit der Schleife fertig sind, hat der erste Stack tatsächlich die Basis. 10 Wert und eine weitere 2. Wir subtrahieren diese 2 mit -, um den Versatz in der Kodierung zu berücksichtigen, und drucken das Zeichen mit !. Der #wirft einfach die Null am Ende der unteren Schleife ab.

Sobald diese Schleife abgeschlossen ist, ist der zweite Stapel leer und der erste Stapel enthält alle Ziffern in umgekehrter Reihenfolge (und a -7unten). Der Rest ist ziemlich einfach:

( 6+ !
8(1-)8)#

Dies ist die zweite Schleife des Kerns, die nun alle Ziffern ausgibt. Dazu müssen wir zu jeder Ziffer 48 eingeben, um den richtigen Zeichencode zu erhalten. Wir machen das mit einer einfachen Schleife, die jedes Mal läuft 8und addiert 6. Das Ergebnis wird mit !und 8am Ende für die nächste Iteration gedruckt .

Was ist mit dem -7? Ja, 48 - 7 = 41das ist der Zeichencode von ). Magie!

Wenn wir mit dieser Schleife fertig sind, verwerfen 8wir die gerade gedrückte #, um sicherzustellen, dass die äußere Schleife für die zweite Stimme belassen wird. Wir geben alle Ziffern erneut ein und das Programm wird beendet.



19
Martin, du musst irgendwo anhalten.
Siehe auch

3
Ich finde es großartig, dass insgesamt über 5000 Bytes golfen wurden, plus eine Bestätigung an Sp3000 für das Speichern von 3 davon.
Kamil Drakari

2
@KamilDrakari Das waren allerdings die letzten 3 Bytes, es ist also eine ziemlich große Sache. ;)
Martin Ender

57

Hexagony , Seitenlänge 11, 314 Bytes

164248894991581511673077637999211259627125600306858995725520485910920851569759793601722945695269172442124287874075294735023125483.....!/:;.........)%'=a':\....................\...................\..................\.................\................\...............\..............\..$@.........\$><>'?2='%.<\:;_;4Q

Probieren Sie es online!


Ältere Version:

Hexagony , Seitenlänge 11, 330 Bytes

362003511553420961423766261426252539048636523959468260999944549820033581478284471415809677091006384959302453627348235790194699306179..../:{;+'=1P'%'a{:..\.....................\...................\..................\.................\................\...............\..............\.............\!$><........\..@>{?2'%<......:;;4Q/

Probieren Sie es online!

Encoder: Online ausprobieren!

Das Programm entspricht in etwa diesem Python-Code: Probieren Sie es online aus!

Ungefalteter Code:

           3 6 2 0 0 3 5 1 1 5 5
          3 4 2 0 9 6 1 4 2 3 7 6
         6 2 6 1 4 2 6 2 5 2 5 3 9
        0 4 8 6 3 6 5 2 3 9 5 9 4 6
       8 2 6 0 9 9 9 9 4 4 5 4 9 8 2
      0 0 3 3 5 8 1 4 7 8 2 8 4 4 7 1
     4 1 5 8 0 9 6 7 7 0 9 1 0 0 6 3 8
    4 9 5 9 3 0 2 4 5 3 6 2 7 3 4 8 2 3
   5 7 9 0 1 9 4 6 9 9 3 0 6 1 7 9 . . .
  . / : { ; + ' = 1 P ' % ' a { : . . \ .
 . . . . . . . . . . . . . . . . . . . . \
  . . . . . . . . . . . . . . . . . . . \ 
   . . . . . . . . . . . . . . . . . . \  
    . . . . . . . . . . . . . . . . . \   
     . . . . . . . . . . . . . . . . \    
      . . . . . . . . . . . . . . . \     
       . . . . . . . . . . . . . . \      
        . . . . . . . . . . . . . \       
         ! $ > < . . . . . . . . \        
          . . @ > { ? 2 ' % < . .         
           . . . . : ; ; 4 Q / .          

Zwei .s dauert 1 Bit. Alle anderen Zeichen enthalten 1 Bit und eine Basis-97-Ziffer.

Erläuterung

Klicken Sie auf die Bilder für eine größere Darstellung. Jeder Erklärungsteil enthält zum besseren Verständnis den entsprechenden Python-Code.

Datenteil

Anstelle der komplexen Struktur in einigen anderen Antworten verwendet (mit <, "und einige andere Dinge), lasse ich nur die IP durch die untere Hälfte passieren.

Daten

Erstens durchläuft die IP viele Nummern und No-Ops ( .) und Mirrors ( \). Jede Ziffer wird an die Nummer im Speicher angehängt, sodass der Speicherwert am Ende der Nummer am Anfang des Programms entspricht.

mem = 362003511...99306179

! druckt es,

stdout.write(str(mem))

und $springt durch die nächsten >.

Ausgehend von der <. Wenn der Speicherwert memfalsch ist ( <= 0dh die Bedingung mem > 0ist nicht erfüllt), haben wir das Programm ausgedruckt und sollten das Programm beenden . Die IP würde dem oberen Pfad folgen.

Ausgang

(Lassen Sie die IP-Adresse für ungefähr 33 Befehle rund um die Welt laufen, bevor Sie die @(die das Programm beendet) drücken, da das Platzieren an einer anderen Stelle einige zusätzliche Bytes erfordert.)

Wenn dies zutrifft, folgen wir dem unteren Pfad, werden einige Male umgeleitet und führen einige weitere Befehle aus, bevor wir eine andere Bedingung treffen.

# Python                    # Hexagony
# go to memory cell (a)     # {
a = 2                       # ?2
# go to memory cell (b)     # '
b = mem % a                 # %

Nun sieht die Erinnerung so aus:

Mem1

Wenn der Wert wahr ist:

if b > 0:

Der folgende Code wird ausgeführt:

# Python                    # Hexagony
b = ord('Q')                # Q
b = b*10+4                  # 4
# Note: now b == ord('.')+256*3
stdout.write(chr(b%256))    # ;
stdout.write(chr(b%256))    # ;

Eine ausführliche Erläuterung der Antwort finden SieQ4 bei MartinEnder unter HelloWorld Hexagony . Kurz gesagt, dieser Code wird .zweimal gedruckt .

Ursprünglich hatte ich geplant, dies .einmal zu drucken . Als ich darauf kam ( .zweimal drucken ) und es implementierte, wurden ungefähr 10 Stellen gespeichert.

Dann,

b = mem // a                # :

Hier ist eine wichtige Tatsache, die mir etwa 14 Stellen erspart hat: Sie müssen nicht an der Stelle sein, an der Sie angefangen haben.


Um zu verstehen, was ich sage, lassen Sie uns eine BF-Analogie haben. (überspringen Sie dies, wenn Sie bereits verstanden haben)

Angesichts des Codes

while a != 0:
    b, a = a * 2, 0
    a, b = b, 0
    print(a)

Angenommen, wir seien ader Wert der aktuellen Zelle und bder Wert der rechten Zelle, dann lautet eine einfache Übersetzung davon in BF:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
    >[-<+>]       # a, b = b, 0
    <.            # print(a)
]

Beachten Sie jedoch, dass wir während des Programms nicht immer an derselben Position sein müssen. Wir können den Wert von aso lassen, wie wir zu Beginn jeder Iteration sind, dann haben wir diesen Code:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
                  # implicitly let (a) be at the position of (b) now
    .             # print(a)
]

Das ist einige Bytes kürzer.


Außerdem erspart mir das Verhalten beim Einwickeln von Ecken einen \Spiegel - ohne diesen könnte ich die Ziffern nicht anpassen (+2 Ziffern für sich \selbst und +2 Ziffern für ein ungepaartes Zeichen .rechts davon, ganz zu schweigen von dem Flaggen)

(Einzelheiten:

  • Die IP tritt in die linke untere Ecke ein und zeigt nach links
  • Es wird in die rechte Ecke verzogen, geht aber immer noch nach links
  • Es trifft auf ein, \das es widerspiegelt, jetzt geht es nach oben
  • Es geht in die Ecke und wird wieder in die untere linke Ecke verzogen

)


Wenn der Wert (der obigen Mod 2-Operation) falsch (Null) ist, folgen wir diesem Pfad:

# Python                 # Hexagony   # Memory visualization after execution
b = mem // a             # :          # click here
base = ord('a') # 97     # a
y = b % base             # '%
offset = 33              # P1
z = y + offset           # ='+
stdout.write(chr(z))     # ;          # click here
mem = b // base          # {:         # click here

Ich werde hier nicht zu detailliert erklären, aber der Versatz ist eigentlich nicht genau 33, aber kongruent zu 33mod 256. Und chrhat eine implizite % 256.


3
Mann, das ist eine Menge No-Ops
Jo King

26
Ich lachte über "Um zu verstehen, was ich sage, lassen Sie uns eine [BrainFuck] Analogie haben." Nur bei PPCG ... :)
Lynn

2
Ich habe 3 mal nach oben gescrollt, um es zu bewerten, nur um herauszufinden, dass ich es bereits getan habe ...
NieDzejkob

2
310 Bytes, indem Sie den neuen Speicherplatz ausnutzen, um die Zahl zu verkürzen
Jo King

2
308 Bytes durch noch mehr Platz
Jo King

46

Vim, 11 Bytes

q"iq"qP<Esc>hqP
  • iq"qP<Esc>: Fügen Sie manuell ein Duplikat des Texts ein, das sich außerhalb der Aufnahme befinden muss.
  • q"und hqP: Nehmen Sie das Innere direkt in das unbenannte ""Register auf, damit es in der Mitte eingefügt werden kann. Das hist die einzige Repositionierung erforderlich; Wenn Sie es in das Makro einfügen, wird es in das Ergebnis eingefügt.

Bearbeiten

Ein Hinweis zum Aufnehmen mit q": Das unbenannte Register ""ist eine lustige Sache. Es ist kein richtiges Register wie die anderen, da dort kein Text gespeichert ist. "-Tatsächlich ist es ein Zeiger auf ein anderes Register (normalerweise für Löschvorgänge ohne Zeilenumbruch, "0für Yanks oder "1für Löschvorgänge mit Zeilenumbruch). q"bricht die Regeln; es schreibt tatsächlich an "0. Wenn Sie ""bereits auf ein anderes Register als verwiesen haben "0, q"wird es überschrieben , bleibt "0jedoch ""unverändert. Wenn Sie ein neues Vim starten, zeigt es ""automatisch auf "0, sodass es Ihnen in diesem Fall gut geht.

Grundsätzlich ist Vim komisch und fehlerhaft.


warte, warum funktioniert das nicht für mich
Destructible Lemon

@ DestructibleWatermelon Kann nicht sicher sagen, aber eine Erklärung ist am wahrscheinlichsten. Hätte es wohl vorher in der Redaktion haben sollen, da es Leute abschrecken kann. Lies die Bearbeitung.
udioica

Sie sollten wahrscheinlich etwas darüber sagen, wie das Drücken yoder etwas vor dem Laufen helfen kann
Destructible Lemon

Warum zeigen Sie nicht das Drücken der <Esc> -Taste? Teil dieses Unicode-Blocks „Control Pictures“
mbomb007

4
@ mbomb007 Die <Esc>Notation ist in Vim-Mappings ( :help <>) Standard und wird von vimgolf.com verwendet. Jeder erfahrene Vimgolfer wird es gewohnt sein, es zu lesen. Was den Unicode betrifft, muss ich schielen, um die kleinen Buchstaben zu lesen, und sie verdecken die Methode, sie einzugeben und die Hilfedatei zu durchsuchen.
Audioica

44

Cubix , 20 Bytes

3434Qu$v@!<"OOw\o;/"

Habe fast die \o/ ...

Netto :

    3 4
    3 4
Q u $ v @ ! < "
O O w \ o ; / "
    . .
    . .

Probieren Sie es online aus

Probieren Sie es hier aus !

Zusätzliche Bemerkungen

Hintergrundgeschichte

Nachdem ich beeindruckt war, diese großartige Antwort von @ ais523 zu lesen, begann ich über das weitere Golfen des Quine nachzudenken. Immerhin gab es dort einige No-Ops, und das fühlte sich nicht sehr komprimiert an. Da die Technik, die seine (und auch meine) Antwort verwendet, erfordert, dass der Code vollständige Zeilen umfasst, war eine Einsparung von mindestens 12 Bytes erforderlich. Es gab eine Bemerkung in seiner Erklärung, die mich wirklich zum Nachdenken brachte:

Was das Golfspielen auf dieser Quine angeht, [...] müsste die Oberseite des Würfels [...] auf eine andere Weise dargestellt werden.

Dann plötzlich, als ich aufstand und wegging, um etwas zu trinken zu holen, fiel mir auf: Was, wenn das Programm keine Zeichencodes, sondern Zahlen zur Darstellung der Oberseite verwendete? Dies ist besonders kurz, wenn die Zahl, die wir drucken, zweistellig ist. Cubix 3 Ein-Byte - Befehle hat zweistellige Zahlen zu drücken: N, Sund Q, die schieben 10, 32und 34jeweils so sollte dies ziemlich Golfy sein, dachte ich.

Die erste Schwierigkeit bei dieser Idee ist, dass die Oberseite jetzt mit unnützen Zahlen gefüllt ist, so dass wir das nicht mehr verwenden können. Die zweite Komplikation ist, dass die Oberseite eine Größe hat, die der quadratischen Größe des Würfels entspricht, und eine gerade Größe haben muss, da sonst auch eine Zahl an der Startposition des Befehlszeigers landen würde, was zu einem verschmutzten Stapel führt. Aufgrund dieser Komplikationen musste mein Code auf einen Würfel der Größe 2 passen (der "nur" 24 Bytes enthalten kann, also musste ich mindestens 21 Bytes abwerfen). Außerdem hatte ich nur 16 effektive Bytes, da die Ober- und Unterseite unbrauchbar sind.

Also wählte ich zunächst die Zahl, die die Hälfte der oberen Fläche ausmachen würde. Ich habe mit N(10) angefangen , aber das hat nicht ganz geklappt, weil ich versucht habe, alles zu drucken. In jedem Fall habe ich neu begonnen und S(32) aus irgendeinem Grund verwendet. Das hat zu einem richtigen Quine geführt, dachte ich. Es hat alles sehr gut funktioniert, aber die Anführungszeichen fehlten. Dann kam mir der Gedanke, dass die Q(34) wirklich nützlich sein würde. Immerhin ist 34 der Zeichencode des doppelten Anführungszeichens, der es uns ermöglicht, ihn auf dem Stapel zu halten und (2, in dem damals verwendeten Layout) wertvolle Bytes zu speichern. Nachdem ich die IP-Route ein wenig geändert hatte, war alles, was übrig blieb, eine Übung, um die Lücken auszufüllen.

Wie es funktioniert

Der Code kann in 5 Teile aufgeteilt werden. Ich werde sie einzeln durchgehen. Beachten Sie, dass wir die mittleren Flächen in umgekehrter Reihenfolge codieren, da das Stack-Modell First-In-Last-Out ist.

Schritt 1: Bedrucken der Oberseite

Die irrelevanten Anweisungen wurden durch No-Ops ( .) ersetzt. Die IP beginnt in der dritten Zeile ganz links und zeigt nach Osten. Der Stapel ist (offensichtlich) leer.

    . .
    . .
Q u . . . . . .
O O . . . . . .
    . .
    . .

Die IP endet an der am weitesten links gelegenen Position in der vierten Zeile und zeigt nach Westen, um sich an der am weitesten rechts gelegenen Position in derselben Zeile zu bewegen. Die ausgeführten Anweisungen lauten (ohne das Kontrollflusszeichen):

QOO
Q   # Push 34 (double quotes) to the stack
 OO # Output twice as number (the top face)

Der Stapel enthält nur 34 Zeichen, die das letzte Zeichen der Quelle darstellen.

Schritt 2: Codieren Sie die vierte Zeile

Dieses Bit macht so ziemlich das, was Sie erwarten: Codieren Sie die vierte Zeile. Die IP beginnt mit dem doppelten Anführungszeichen am Ende dieser Zeile und geht nach Westen, während die Zeichencodes aller Zeichen gedrückt werden, auf denen sie landen, bis ein übereinstimmendes doppeltes Anführungszeichen gefunden wird. Dieses übereinstimmende doppelte Anführungszeichen ist auch das letzte Zeichen in der vierten Zeile, da die IP-Adresse erneut umgebrochen wird, wenn sie den linken Rand erreicht.

Tatsächlich ist die IP um eine Position nach links verschoben worden, und der Stapel enthält jetzt die Darstellung der vierten Zeile in Zeichencodes und umgekehrter Reihenfolge.

Schritt 3: Drücken Sie ein anderes Zitat

Wir müssen ein weiteres Zitat vorlegen, und wie kann man das Qam Anfang des Programms besser recyceln , indem man es von rechts betrachtet? Dies hat den zusätzlichen Bonus, dass die IP direkt in das Zitat läuft, das die dritte Zeile codiert.

Hier ist die Netzversion für diesen Schritt. Irrelevante Eingriffe wurden wieder durch No-Ops ersetzt, die ausgeführten No-Ops wurden #zu Illustrationszwecken durch Hashtags ( ) ersetzt und die IP beginnt beim letzten Zeichen in der vierten Zeile.

    . .
    . .
Q u $ . . . . .
. . w \ . . / .
    . #
    . #

Die IP endet in der dritten Zeile bei der ersten Anweisung und wird am Ende dieser Zeile umgebrochen, da sie nach Westen zeigt. Die folgenden Anweisungen (ohne Kontrollfluss) werden ausgeführt:

$uQ
$u  # Don't do anthing
  Q # Push the double quote

Dieses doppelte Anführungszeichen steht am Ende der dritten Zeile.

Schritt 4: Kodieren der dritten Zeile

Dies funktioniert genauso wie in Schritt 2, daher suchen Sie dort nach einer Erklärung.

Schritt 5: Drucken Sie den Stapel

Der Stapel enthält nun die vierte und dritte Zeile in umgekehrter Reihenfolge. Sie müssen ihn also nur noch drucken. Die IP beginnt mit der vorletzten Anweisung in der dritten Zeile und bewegt sich nach Westen. Hier ist der relevante Teil des Würfels (wieder wurden irrelevante Teile durch No-Ops ersetzt).

    . .
    . .
. . . v @ ! < .
. . . \ o ; / .
    . .
    . .

Dies ist eine Schleife, wie Sie vielleicht gesehen / erwartet haben. Der Hauptteil ist:

o;
o  # Print top of stack as character
 ; # Delete top of stack

Die Schleife endet, wenn das oberste Element 0 ist. Dies geschieht nur, wenn der Stapel leer ist. Wenn die Schleife endet, @wird ausgeführt und das Programm beendet.


Ich wünschte, ich könnte dies mehr
befürworten

Kopfgelder sind immer willkommen ;-)
Luke

42

Javascript ES6 - 21 Bytes

$=_=>`$=${$};$()`;$()

Ich nenne das Quine "The Bling Quine".

Manchmal muss man stilvoll Golf spielen.


Spart !$=_=>`!$=${$}()`()Ihnen 2 Bytes?
Downgoat

Invalid assignment left hand side. Ich wünschte, es hat funktioniert :(
Mama Fun Roll

1
@ TùxCräftîñg Das Eliminieren von Klammern um Vorlagenliterale funktioniert nur für native Prototypfunktionen, z Array.prototype.join.
Mama Fun Roll

2
Hmm, nicht sicher. Ich habe das vor über einem Jahr geschrieben (es galt damals als gültig) und ich habe die Änderungen der Regeln für Quine nicht zu genau verfolgt. Das Hinzufügen alertoder console.lognach der Pfeilfunktion und das Umschließen der Vorlagenzeichenfolge in Klammern würde jedoch funktionieren.
Mama Fun Roll

3
Auch wenn Sie dies in der Concole ausführen, überschreibt es $ (jQuery-Funktion) auf dieser Site und die Upvote-Funktion funktioniert nicht mehr. :)
Steven Palinkas

41

Brainf * ck (755 Zeichen)

Dies basiert auf einer von Erik Bosman (ejbosman at cs.vu.nl) entwickelten Technik. Beachten Sie, dass die "ESultanik's Quine!" Text ist eigentlich notwendig, damit es ein Quine ist!

->++>+++>+>+>++>>+>+>+++>>+>+>++>+++>+++>+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>++>>>+++>>>>>+++>+>>>>>>>>>>>>>>>>>>>>>>+++>>>>>>>++>+++>+++>+>>+++>>>+++>+>+++>+>++>+++>>>+>+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++>+++>+>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++>+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>>+++++++++++++++>+++++++++++++>++++++>+++++++++++++++>++++++++++>+++>+++>++++>++++++++++++++>+++>++++++++++>++++>++++++>++>+++++>+++++++++++++++>++++++++>++++>++++++++++++>+++++++++++++++>>++++>++++++++++++++>+++>+++>++++>++++++>+++>+++++++++>++++>+>++++>++++++++++>++++>++++++++>++>++++++++++>+>+++++++++++++++>+++++++++++++
ESultanik's Quine!
+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]>>+[>]+++[++++++++++>++[-<++++++++++++++++>]<.<-<]

13
Das ist eine clevere Methode.
Peter Olson

13
Wie funktioniert es?
stolzer Haskeller

3
@proudhaskeller IIRC, der Teil vor dem ESultanik's Quine!Einrichten des Speichers als Stapelcodierung ESultanik's Quine!und weiter, mit zwei Byte Speicher für jedes Zeichen (ASCII-Wert versetzt von 0x1F). Das letzte Codebit durchläuft den Speicher, wobei zuerst die ++>+++…Codes für jedes Zeichen programmgesteuert reproduziert und dann die Zeichen tatsächlich gedruckt werden.
ESultanik

4
@CatsAreFluffy Sie werden benötigt, damit es ein Quine ist! Sie könnten zwar entfernt werden, aber man müsste auch den vorhergehenden Code ändern, um die quine-Eigenschaft beizubehalten.
ESultanik

1
Das ist richtig. Auch die Zeilenumbrüche sind notwendig.
CalculatorFeline

36

Sechseck , Seitenlänge 15 14 13 12, 616 533 456 383 Bytes

Nach einigen Tagen sorgfältigen Golfspiels, Neuanordnens von Loops und Neuanfangens habe ich es endlich geschafft, es auf ein Sechseck von Seite 12 zu bringen.

1845711724004994017660745324800783542810548755533855003470320302321248615173041097895645488030498537186418612923408209003405383437728326777573965676397524751468186829816614632962096935858"">./<$;-<.....>,.........==.........<"......."">'....>+'\.>.........==........<"......"">:>)<$=<..>..............$..<"...."">\'Q4;="/@>...............<"....."">P='%<.>.............<"..!'<.\=6,'/>

Probieren Sie es online!

Entfaltet:

            1 8 4 5 7 1 1 7 2 4 0 0
           4 9 9 4 0 1 7 6 6 0 7 4 5
          3 2 4 8 0 0 7 8 3 5 4 2 8 1
         0 5 4 8 7 5 5 5 3 3 8 5 5 0 0
        3 4 7 0 3 2 0 3 0 2 3 2 1 2 4 8
       6 1 5 1 7 3 0 4 1 0 9 7 8 9 5 6 4
      5 4 8 8 0 3 0 4 9 8 5 3 7 1 8 6 4 1
     8 6 1 2 9 2 3 4 0 8 2 0 9 0 0 3 4 0 5
    3 8 3 4 3 7 7 2 8 3 2 6 7 7 7 5 7 3 9 6
   5 6 7 6 3 9 7 5 2 4 7 5 1 4 6 8 1 8 6 8 2
  9 8 1 6 6 1 4 6 3 2 9 6 2 0 9 6 9 3 5 8 5 8
 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
           ! ' < . \ = 6 , ' / > . .
            . . . . . . . . . . . .

Obwohl es nicht so aussieht, als wäre es der meiste Hexagony-Code, ist die von mir verwendete Codierung für längere Läufe von No-Ops optimiert, was Sie sonst vermeiden würden.

Erläuterung

Dies schlägt die vorherige Hexagony-Antwort, indem die no-ops ( .) auf andere Weise codiert werden. Während diese Antwort Platz spart, indem Sie jedes andere Zeichen zu einem a machen ., codiert meins die Anzahl der No-Ops. Dies bedeutet auch, dass die Quelle nicht so eingeschränkt sein muss.

Hier verwende ich eine Basis 80 Codierung, wo Zahlen unter 16 läuft der No-ops zeigen und Zahlen zwischen 16 und 79 stellen den Bereich 32 ( !) bis 95 ( _) (Ich bin jetzt nur noch zu realisieren ich golfed alle _s aus meinem Code lol). Pythonischer Pseudocode:

i = absurdly long number
print(i)
base = 80
n = i%base
while n:
    if n < 16:
        print("."*(16-n))
    else:
        print(ASCII(n+16))
    i = i//base
    n = i%base

Die Zahl wird in der ersten Hälfte des Sechsecks mit allen Zeichen codiert

" " > 
 " " > 
  ... etc

auf der linken Seite und der

 > ,
< "
 >
< "
... etc

auf der rechten Seite den Zeiger umleiten, um die Zahl in eine Zelle zu kodieren. Dies ist Martin Enders Antwort entnommen (danke), da ich keinen effizienteren Weg finden konnte.

Es gelangt dann in den unteren Bereich durch ->:

       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
     ->    ! ' < . \ = 6 , ' / > . .

!druckt die Nummer und 'navigiert zur rechten Speicherzelle, bevor die Schleife gestartet wird. P='%modifiziert die aktuelle Zahl um 80. Wenn das Ergebnis 0 ist, gehe hoch zum Abschluss @, sonst gehe runter und erstelle eine Zelle neben dem Mod-Ergebnis mit dem Wert -16.

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
                      /
                     /

Stellen Sie die Zelle auf (Mod-Wert + -16). Wenn dieser Wert negativ ist, gehen Sie an der Verzweigung nach oben >+'\, andernfalls nach unten.

Wenn der Wert positiv ist:

 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .

Der Zeiger landet an der Stelle, an der ;-<die Zelle steht (mod value - -16) und gibt sie aus.

Der Wert ist negativ:

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .

Gehen Sie zu dem > ) <Abschnitt, der die Schleife startet. Hier ist es isoliert:

     . . > ) < $ = < . .
      . . . . . . . . .
       \ ' Q 4 ; = " /

Dieser führt den Code aus, 'Q4;="=der ein ausgibt .(nochmals danke an Martin Ender, der ein Programm geschrieben hat , um die Buchstaben-Zahlen-Kombinationen für Zeichen zu finden) und geht zurück in die Startzelle. Anschließend wird )die Mod-Wert-Zelle inkrementiert ( ) und erneut eine Schleife ausgeführt, bis der Mod-Wert positiv ist.

Wenn das erledigt ist, bewegt es sich nach oben und verbindet sich mit dem anderen Abschnitt unter:

 " " > . / < $ ; - < . . .
            \
             \

Der Zeiger springt dann wieder zum Anfang der größeren Schleife zurück

 " " > . / <--
  . . . = =
   . " " > ' 
    . . . = = 
     . " " > :
      . . . . .
       " " > \ ' . .
        . . . . . . .
         . . " " > P = ' % < . > . . .

Dies wird ausgeführt, ='=:'wobei die aktuelle Zahl durch 80 geteilt wird und zur richtigen Zelle navigiert wird.

Alte Version (Seitenlänge 13)

343492224739614249922260393321622160373961419962223434213460086222642247615159528192623434203460066247203920342162343419346017616112622045226041621962343418346002622192616220391962343417346001406218603959366061583947623434"">/':=<$;'<.....>(......................<"......"">....'...>=\..>.....................<"....."">....>)<.-...>...........==......<"...."">.."...'.../>.................<"..."">\Q4;3=/.@.>...............<".."".>c)='%<..>..!'<.\1*='/.\""

Probieren Sie es online!

Ich kann definitiv eine andere Nebenlänge Golf spielen, aber ich muss es bis morgen lassen, weil es spät wird. Es stellt sich heraus, dass ich ungeduldig bin und nicht bis morgen warten kann. Vielleicht kann eine andere Seite Golf spielen? :( ahhhhhhhhh ich habe es getan!

Ich habe sogar ein paar zusätzliche Ziffern mit einer Base-77-Codierung abgespielt , aber das spielt keine Rolle, da es den gleichen Bytecount hat.


13
Das ist großartig. Die Idee für diese Hybrid-Lauflängencodierung ist wirklich gut. :) Erinnere mich daran, dir ein Kopfgeld zu geben, wenn ich es vergesse.
Martin Ender

35

PostScript, 20 Zeichen

Kurz und richtig. 20 Zeichen inklusive nachfolgender Newline.

(dup == =)
dup == =

33

Cubix , 45 Bytes

.....>...R$R....W..^".<R.!'.\)!'"R@>>o;?/o'u"

Sie können diesen Code hier testen .

Dieses Programm ist ziemlich schwer zu befolgen, aber um eine Chance zu haben, müssen wir es zunächst zu einem Cube erweitern, wie es der Cubix-Interpreter tut:

      . . .
      . . >
      . . .
R $ R . . . . W . . ^ "
. < R . ! ' . \ ) ! ' "
R @ > > o ; ? / o ' u "
      . . .
      . . .
      . . .

Dies ist eine Art Befunge-Quine, die über das Ausnutzen von Wrapping funktioniert, um String-Literale in ausführbaren Code "einfließen" zu lassen (mit nur einer "Markierung befindet sich der Code gleichzeitig sowohl innerhalb als auch außerhalb des Zitats, was möglich wird, wenn Sie haben nichtlineare und nichtplanare Programme). Beachten Sie, dass dies unserer Definition eines richtigen Quines entspricht, da sich zwei der doppelten Anführungszeichen nicht selbst codieren, sondern später mithilfe von Arithmetik berechnet werden.

Im Gegensatz zu Befunge verwenden wir hier jedoch nicht nur eine, sondern vier Saiten. Hier ist, wie sie auf den Stapel geschoben werden;

  1. Das Programm beginnt oben am linken Rand und läuft nach rechts. es dreht sich zweimal nach rechts ( R) und bewegt sich dabei entlang der dritten und letzten Linie, die den gesamten Würfel umgibt, nach links. Das doppelte Anführungszeichen passt zu sich selbst, also schieben wir die gesamte dritte Zeile rückwärts auf den Stapel. Dann wird die Ausführung nach dem Anführungszeichen fortgesetzt.

  2. Der uBefehl führt eine Kehrtwende nach rechts aus, sodass wir als Nächstes von nun '"an auf der Mittellinie fahren. Das drückt einen "auf den Stapel. Wir wickeln uns weiter umher, treffen die <linke Seite des Würfels und hüpfen zurück. Wenn wir uns aus dieser Richtung nähern, sehen wir einen einfachen "Befehl, nicht jedoch '", und die gesamte zweite Zeile wird rückwärts über der dritten Zeile und dem doppelten Anführungszeichen auf den Stapel geschoben.

  3. Wir beginnen damit, dass wir a !auf den Stapel schieben ( '!) und inkrementieren ( )); Dies erzeugt ein doppeltes Anführungszeichen, ohne dass ein doppeltes Anführungszeichen in unserem Quellcode erforderlich ist (was die Zeichenfolge beenden würde). Ein Spiegel ( \) spiegelt die Ausführungsrichtung nach Norden wider; dann geht der WBefehl zur linken Seite. Dies lässt uns in der siebten Spalte nach oben gehen. Da dies ein Würfel ist, wird er in der dritten Zeile nach links und in der dritten Spalte nach unten gewickelt. Wir schlagen ein R, um rechts abzubiegen und gehen links entlang der oberen Reihe; Dann $überspringt das den Weg, Rüber den wir das Programm eingegeben haben, so dass die Ausführung "am Ende der Zeile endet und wir die erste Zeile in einer Zeichenkette auf die gleiche Weise erfassen, wie wir es für die zweite und dritte Zeile getan haben.

  4. Der ^Befehl schickt uns in nördlicher Richtung die elfte Spalte hinauf, die in südlicher Richtung die fünfte ist (Würfelumhüllung erlaubt). Das Einzige, was uns dort begegnet, ist !(Skip, wenn nicht Null; die Spitze des Stapels ist tatsächlich ungleich Null), das den oBefehl überspringt und die fünfte Spalte praktisch vollständig leer macht. Also ukehren wir zu dem Befehl zurück, der erneut umkehrt, aber diesmal bleiben wir auf der letzten Spalte nach Süden, die zur vierten Spalte nach Norden führt. Wir haben jedoch während der Kehrtwende ein doppeltes Anführungszeichen getroffen, sodass wir die gesamte vierte Spalte in einer Zeichenfolge von unten nach oben erfassen. Im Gegensatz zu den meisten Anführungszeichen im Programm schließt sich dieses nicht von alleine. Vielmehr wird es durch das Symbol "in der rechten oberen Ecke geschlossen, was bedeutet, dass wir die Zeichenfolge mit neun Zeichen erfassen ...>......

Das Stack-Layout ist also jetzt von oben nach unten: vierte Spalte; oberste Reihe; "; mittlere Reihe; "; untere Reihe. Jedes dieser Zeichen wird auf dem Stapel mit dem ersten Zeichen am Anfang des Stapels dargestellt (Cubix drückt Zeichenfolgen in umgekehrter Reihenfolge wie Befunge, aber jedes Mal, wenn sich die IP in die entgegengesetzte Richtung zur natürlichen Leserichtung bewegt hat, so wurde es effektiv zweimal umgekehrt). Es ist anzumerken, dass der Inhalt des Stapels fast identisch mit dem ursprünglichen Programm ist (da die vierte Spalte und die Nord- / Oberseite des Würfels dieselben Zeichen in derselben Reihenfolge enthalten; offensichtlich wurde sie absichtlich so gestaltet).

Der nächste Schritt besteht darin, den Inhalt des Stapels zu drucken. Nach all den Pushs geht die IP in der vierten Spalte nach Norden, trifft >dort also und tritt in eine enge Schleife ein >>o;?(dh "nach Osten drehen, nach Osten drehen, als Zeichen ausgeben, Pop, nach rechts drehen, wenn positiv"). Da die siebte Zeile mit NOPs gefüllt ist, wird der Zeilenumbruch ?auf die erste zurückgesetzt >, sodass der gesamte Inhalt des Stapels effektiv verschoben wird ( ?bei einem leeren Stapel ist dies ein No-Op). Wir haben fast das gesamte Programm ausgedruckt! Leider ist es noch nicht ganz fertig; Wir vermissen das doppelte Anführungszeichen am Ende.

Sobald die Schleife endet, reflektieren wir über ein Paar Spiegel auf die Mittellinie, die sich nach Westen bewegt. (Wir haben früher die "andere Seite" des \Spiegels verwendet; jetzt verwenden wir die Südwestseite. Der /Spiegel wurde zuvor nicht verwendet.) Wir '!treffen auf ein Ausrufezeichen (dh 33; wir verwenden ASCII) und Cubix unterscheidet nicht zwischen ganzen Zahlen und Zeichen auf dem Stapel. (Praktischerweise ist dies das gleiche, mit !dem der oBefehl früher übersprungen wurde.) Wir Rtreffen auf ein RBefehlspaar und verwenden es, um eine "manuelle" Kehrtwende durchzuführen (der zweite Befehl hier wurde früher verwendet, um den ersten zu erreichen Reihe, so schien es am natürlichsten, einen anderen RBefehl daneben zu passen .WBefehl, um nach links auszuweichen. Der Sidestep stürzt direkt in den >Befehl in der zweiten Zeile und bringt die Ausführung genau dahin zurück, wo sie war. Wir gehen also wieder nach links, aber dieses Mal gehen wir nach Süden, und der nächste auszuführende Befehl ist der )(Inkrementieren des Ausrufezeichens in ein doppeltes Anführungszeichen), gefolgt von einem o(um es auszugeben). Schließlich wird die Ausführung entlang der achten Zeile bis zur zweiten Spalte fortgesetzt, wo ein gefunden wird @, um das Programm zu beenden.

Ich entschuldige mich für das verirrte Apostroph in der dritten Zeile. In dieser Version des Programms wird nichts ausgeführt. es war Teil einer früheren Idee, die ich hatte, die sich jedoch als nicht notwendig herausstellte. Sobald ich jedoch ein funktionierendes Quine erhalten hatte, wollte ich es nur einreichen, anstatt weiter damit herumzuspielen, zumal das Entfernen die Byteanzahl nicht ändern würde. Was das weitere Golfspielen angeht, würde es mich nicht überraschen, wenn dies bei 3 × 3 nur mit den ersten fünf Linien möglich wäre, aber ich sehe keinen offensichtlichen Weg, dies zu tun, und es würde notwendig sein noch engere Packung des gesamten Kontrollflusses zusammen mit einer anderen Möglichkeit, die Oberseite des Würfels darzustellen (oder den Algorithmus so zu modifizieren, dass die vierte Spalte weiterhin verwendet werden kann, obwohl sie jetzt zehn oder elf Zeichen lang wäre) .


Gute Arbeit, das ist eine wirklich beeindruckende Punktzahl. Ich liebe es, wie du das obere Gesicht kodiert hast. :)
Martin Ender

Das ist einfach unglaublich! Wenn es irgendwelche helfen würde, einen anderen Weg zu schieben "ist Q.
ETHproductions

1
Beeindruckend! Ich hätte nie gedacht, dass ich einen Cubix Quine sehen würde!
FlipTack

3
Ich hatte gestern keine Zeit, die Erklärung zu lesen, aber jetzt, wo ich ... Nur ... WOW. Ich kann nicht glauben, wie viele Zeichen für zwei oder sogar drei völlig unterschiedliche Zwecke verwendet werden. Dies ist wahrscheinlich das coolste Cubix-Programm, das ich je gesehen habe.
ETHproductions

Gute Erklärung.
Robert Fraser

33

Python 2, 30 Bytes

_='_=%r;print _%%_';print _%_

Von hier genommen


1
+1, du hast meine ähnliche Lösung besiegt und ich habe sie gelöscht. Es sollte beachtet werden, dass dies nur in Python 2 funktioniert.
nyuszika7h

2
Es sieht komisch aus mit dem Variablennamen als _, aber es liest sich besser, wenn Sie es einem Buchstaben zuweisen, dh s:s='s=%r;print s%%s';print s%s
Ehtesh Choudhury

5
Wenn diese Lösung nicht von Ihnen selbst erstellt wurde, sollten Sie sie zum Community-Wiki machen. Auch der Link ist tot.
mbomb007

1
Ich bin ein bisschen zu spät zur Party, aber kann jemand erklären, wie das funktioniert?
MadTux

9
Dies erfordert einen nachgestellten Zeilenvorschub, um gültig zu sein. So wie es ist, stimmt der Quellcode nicht mit der Ausgabe überein.
Dennis

32

Vim, 17 , 14 Tastenanschläge

Jemand hat das nach dem Zufallsprinzip hochgestuft, also erinnerte ich mich, dass es existiert. Als ich es noch einmal las, dachte ich: "Hey, ich kann es besser als das!", Also habe ich zwei Bytes weniger gespielt. Es ist immer noch nicht die kürzeste, aber zumindest eine Verbesserung.


Ich habe mich lange gefragt, ob ein vim quine möglich ist. Einerseits muss es möglich sein, da vim vollständig ist. Aber nachdem ich sehr lange nach einer Quine gesucht hatte, konnte ich keine finden. Ich habe finden diese PPCG Herausforderung , aber es ist geschlossen und nicht genau über wörtliche quines. Also habe ich beschlossen, eine zu machen, da ich keine finden konnte.

Auf diese Antwort bin ich aus zwei Gründen sehr stolz :

  1. Dies ist die erste Quine, die ich jemals gemacht habe, und

  2. Soweit ich weiß, ist dies die erste vim-quine der Welt , die jemals veröffentlicht wurde! Ich könnte mich in dieser Sache irren. Wenn Sie eine kennen, lassen Sie es mich bitte wissen.

Also, nach dieser langen Einführung, hier ist es:

qqX"qpAq@q<esc>q@q

Probieren Sie es online!

Beachten Sie, dass der <esc>Tastenanschlag bei der Eingabe als angezeigt wird ^[. Dies ist immer noch korrekt, da ^[repräsentiert 0x1B, was in ASCII ein Escape ist , und die Art und Weise, wie vim intern den <esc>Schlüssel repräsentiert .

Auch beachten Sie , dass diese Prüfung fehlschlagen , wenn Sie eine vorhandene vim Sitzung laden. Ich schrieb ein beantworten , die erklären hier , wenn Sie weitere Informationen wünschen, aber im Grunde müssen Sie vim starten mit

vim -u NONE -N -i NONE

oder tippe qqqbevor du das ausführst.

Erläuterung:

qq                  " Start recording into register 'q'
  X                 " Delete one character before the cursor (Once we play this back, it will delete the '@')
   "qp              " Paste register 'q'
      Aq@q<esc>     " Append 'q@q' to this line
               q    " Stop recording
                @q  " Playback register 'q'

Nebenbei bemerkt, diese Antwort ist wahrscheinlich ein Weltrekord für die meisten Fragen in einer PPCG-Antwort oder so.


1
2i2i<esc>ist so nah. Ich habe das Gefühl, dass es etwas geben muss, das ich tun kann, damit das funktioniert.
Zwei

@zwei Ich weiß, es ist knapp, es tut weh! Eigentlich <Esc>ist in V implizit, so dass funktioniert . Leider gibt es auch eine neue Zeile, weshalb ich sie noch nicht gepostet habe.
DJMcMayhem

q"iq"qbP<Esc>qbPist 11. Nachdem du das auf reddit gesetzt hast , habe ich hier das Vimgolfing untersucht und beschlossen, ein Konto zu erstellen. Dies ist die Antwort, die ich dort gepostet habe.
Audioica

2
@udioica Kannst du das als Antwort posten?
DJMcMayhem

28

Verloren , 120 116 98 96 76 70 66 Bytes

Bearbeiten: yay, unter 100

Bearbeiten: Speichert eine Menge Bytes, indem auf alle /s in der untersten Zeile gewechselt wird

:2+52*95*2+>::1?:[:[[[[@^%?>([ "
////////////////////////////////

Probieren Sie es online! + Überprüfung ist deterministisch für alle möglichen Zustände

Lost ist eine 2D-Sprache, in der Startposition und Richtung völlig zufällig sind. Dies bedeutet, dass in jeder Phase viele Fehlerprüfungen durchgeführt werden müssen, um sicherzustellen, dass Sie den richtigen Anweisungszeiger haben, und dass dieser nicht zufällig eingewandert ist.

Erläuterung:

Alle /s in der untersten Zeile sind dazu da, um sicherzustellen, dass alle Zeiger, die in vertikaler Richtung oder in der untersten Zeile erscheinen, in die richtige Richtung geleitet werden. Von dort aus landen sie an verschiedenen Orten, aber alle landen direkt in der

 ^%?>
 ////

Damit werden alle Zahlen ungleich Null im Stapel gelöscht. Der ([nach , die keine zusätzlichen 0s auch entrümpelt.

In der Mitte des Clear trifft es das %, was die "Sicherheit" ausschaltet, was es dem Programm ermöglicht, zu beenden, wenn es das trifft @(ohne dies könnte das Programm sofort enden, wenn ein Zeiger auf das gestartet wird @).

Von dort aus wird eine ziemlich einfache 2D-Sprache erstellt, indem ein String-Literal ( ") um die erste Zeile "gewickelt und ein Zeichen durch Betätigen eines Leerzeichens ( :2+) und einer neuen Zeile ( 52*) verschoben wird . In der zweiten Zeile wird ein /Zeichen ( 95*2+) erstellt und ein Bündel ( >::1?:[:[[[[) dupliziert , bevor es schließlich am endet @und der Stapel implizit gedruckt wird. Das ?1ist es, den Prozess zu stoppen von zu vielen 0s zu schaffen , wenn der Zeiger früh eintritt, Speicher auf, die sie später zu löschen.

Ich habe hier 20 Bytes gespart, indem ich die letzte Zeile immer mit dem gleichen Zeichen versehen habe, was bedeutet, dass ich direkt vom Duping-Prozess bis zum Ende gehen konnte @.

Erklärung zum Duping-Vorgang:

[ist ein Charakter, der als "Tür" bekannt ist. Wenn der Zeiger auf die flache Seite von a [oder a trifft ], wird er reflektiert, ansonsten passiert er es. Jedes Mal, wenn der Zeiger mit einer Tür interagiert, wechselt er zum entgegengesetzten Typ. Mit diesem Wissen können wir eine einfache Formel erstellen, wie oft eine Anweisung in einem >:[Block ausgeführt wird.

Fügen Sie die anfängliche Menge an Anweisungen hinzu. Fügen Sie jeweils [das Doppelte der Anweisungen links davon hinzu. Für das Beispiel >::::[:[[[beginnen wir mit 5 als Anfangsbetrag. Die erste Tür hat 4 Dup-Anweisungen, also addieren wir 4 * 2 = 8 bis 5, um 13 zu erhalten. Die anderen drei Türen haben 5 Dupes zu ihrer Linken, also addieren wir 3 * (5 * 2) = 30 bis 13, um 43 zu erhalten dupe Anweisungen ausgeführt, und haben 44 >s auf dem Stapel. Der gleiche Vorgang kann auf andere Anweisungen angewendet werden, z. B. (um eine große Menge von Elementen aus dem Stapel in den Bereich zu verschieben oder um Elemente aus dem Stapel zu löschen.

Ein Trick, den ich hier benutzt habe, um zu vermeiden, zu viele Nullen zu täuschen, ist der 1?. Wenn das Zeichen 0 ist, ?wird die 1 nicht übersprungen, was bedeutet, dass 1 für den Rest der Dupe dupliziert wird. Dies erleichtert das spätere Löschen des Stapels erheblich .


25

Dies sind die beiden kürzesten Rubin quines von SO :

_="_=%p;puts _%%_";puts _%_

und

puts <<2*2,2
puts <<2*2,2
2

Frag mich nicht, wie der zweite funktioniert ...


8
Der zweite benutzt heredoc, <<2beginnt eine Zeichenkette in der nächsten Zeile und *2wiederholt die Zeichenkette
Ming-Tang

Warum brauchst du die 2?
CalculatorFeline

1
@CalculatorFeline Dies ist der Abschluss des Heredoc-Strings (der in einer eigenen Zeile stehen muss). Eigentlich muss es aber keine 2 sein: tio.run/##KypNqvz/v6C0pFjBxsZAy0jHgAuFY8D1/z8A
Martin Ender

25

Spaltung , 6 Bytes

Es scheint, dass dies nun die kürzeste "richtige" Antwort unter diesen Antworten ist.

'!+OR"

Erläuterung

Der Kontrollfluss beginnt Rmit einem einzelnen rechtsgerichteten (1,0)Atom. Der "Druckmodus wird umgeschaltet und anschließend um die Zeile gewickelt. Anschließend wird gedruckt, '!+ORbevor derselbe "erneut getroffen und der Druckmodus beendet wird.

Das lässt "sich ausdrucken. Der kürzeste Weg ist '"O(wobei '"die Masse des Atoms auf den Zeichencode von gesetzt wird "und Odas Zeichen gedruckt und das Atom zerstört wird), aber wenn wir dies tun, würde dies den "Druckmodus stören. Also setzen wir stattdessen den Wert des Atoms auf '!(eins weniger als "), inkrementieren dann mit +und drucken dann das Ergebnis mit O.

Alternativen

Hier sind ein paar Alternativen, die länger sind, aber vielleicht inspirieren ihre Techniken jemanden, eine kürzere Version mit ihnen zu finden (oder vielleicht sind sie in bestimmten verallgemeinerten Quines nützlicher).

8 Bytes mit Jump

' |R@JO"

Wieder beginnt der Code bei R. Die @tauscht Masse und Energie zu geben (0,1). Dadurch Jspringt das Atom über die OGerade auf die ". Dann werden, wie zuvor, alle außer den "im Zeichenkettenmodus gedruckt. Danach schlägt das Atom |um, um seine Richtung umzukehren, und durchläuft dann den '"ODruckvorgang ". Der Raum ist ein bisschen nervig, aber es scheint notwendig, weil sonst 'das Atom das |als Zeichen anstelle eines Spiegels behandeln würde.

8 Bytes mit zwei Atomen

"'L;R@JO

Dies hat zwei Atome, die von links nach Lrechts gehen R. Das nach links gehende Atom bekommt seinen Wert gesetzt, mit '"dem dann sofort gedruckt wird O(und das Atom zerstört wird). Für das rechtsgerichtete Atom tauschen wir wieder Masse und Energie aus, springen über das O, um den Rest des Codes im Druckmodus zu drucken. Danach wird sein Wert durch gesetzt, 'Laber das spielt keine Rolle, da das Atom dann mit verworfen wird ;.


Technisch ungültig wegen fehlender Code- / Datentrennung in der Quelle.
CalculatorFeline

4
@CalculatorFeline '!+codiert ".
Martin Ender

Ich kenne mich mit Fission nicht aus, würde aber |R@JO"'funktionieren, oder würdest du den Platz nach dem noch brauchen '?
MildlyMilquetoast

1
@MistahFiggins Ich denke schon, aber was noch wichtiger ist, Sie würden die 'erste drucken .
Martin Ender

24

Browserübergreifendes JavaScript (41 Zeichen)

Es funktioniert in den Top 5 Webbrowsern (IE> = 8, Mozilla Firefox, Google Chrome, Safari, Opera). Geben Sie es in die Entwicklerkonsole ein:

eval(I="'eval(I='+JSON.stringify(I)+')'")

Es ist kein "Schummeln" - im Gegensatz zu Chris Jester-Youngs Single-Byte-Quine, da es leicht modifiziert werden könnte, um die alert()Funktion zu nutzen (mit 14 Zeichen):

alert(eval(I="'alert(eval(I='+JSON.stringify(I)+'))'"))

Oder konvertiert in ein Lesezeichen (mit 22 Zeichen):

javascript:eval(I="'javascript:eval(I='+JSON.stringify(I)+')'")

24

C 64 60 Bytes

main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}

Bisher ist dies die kürzeste bekannte C-Quine. Es gibt ein erweitertes Kopfgeld, wenn Sie ein kürzeres finden.

Dies funktioniert in GCC , Clang und TCC in einer POSIX- Umgebung. Es ruft bei allen eine übermäßige Menge an undefiniertem Verhalten hervor.

Nur zum Spaß, hier ist ein Repo , das alle mir bekannten C-Quines enthält. Fühlen Sie sich frei, sich mit PR zu befassen, wenn Sie einen anderen finden oder schreiben, der etwas Neues und Kreatives über die vorhandenen hinzufügt.

Beachten Sie, dass es nur in einer ASCII- Umgebung funktioniert . Dies funktioniert für EBCDIC , erfordert jedoch weiterhin POSIX . Viel Glück beim Auffinden einer POSIX / EBCDIC-Umgebung: P


Wie es funktioniert:

  1. main(s)missbraucht maindie Argumente und deklariert eine praktisch untypisierte Variable s. (Beachten Sie, dass ses sich nicht wirklich um einen untypisierten Compiler handelt. Da die aufgelisteten Compiler ihn jedoch bei Bedarf automatisch umwandeln, kann er auch * lauten.)
  2. printf(s="..."Legt sdie angegebene Zeichenfolge fest und übergibt das erste Argument an printf.
  3. sist eingestellt auf main(s){printf(s=%c%s%1$c,34,s);}.
  4. Das %cist auf ASCII gesetzt 34, ". Das macht das Quine möglich. Nun ssieht wie folgt aus :
    main(s){printf(s="%s%1$c,34,s);}.
  5. Der %sist auf sich sselbst eingestellt, was durch # 2 möglich ist. Nun ssieht wie folgt aus :
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);}.
  6. Der %1$cwird auf ASCII 34 gesetzt ", printfdas erste ** Argument. Nun ssieht es so aus:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
    ... was zufällig der ursprüngliche Quellcode ist.

* Beispiel dank @Pavel
** erstes Argument nach dem Formatbezeichner - in diesem Fall s. Es ist unmöglich, auf den Formatbezeichner zu verweisen.


Ich denke, es ist unmöglich, dass dies mit dem gleichen Ansatz kürzer wird. Wenn printfder Formatbezeichner von über zugänglich $wäre, würde dies für 52 Bytes funktionieren:

main(){printf("main(){printf(%c%0$s%1$c,34);}",34);}

Der Gewinner des 1994 International Obfuscated C Code Contest, 1994_smr.c , ist definitiv kürzer.
Ray

@Ray Es ist nicht erlaubt. Es ist per Definition keine richtige Quine. Die Grundregeln wurden aufgrund dieses Programms geändert: P
MD XF

Ich stimme vollkommen zu, aber es ist interessant genug, dass es sich lohnt zu erwähnen, wenn jemand eine kleinste bekannte Quine erwähnt, schon aus historischen Gründen.
Ray

4
sist vom Typ int, keine "untypisierte Variable".
Feersum

2
Alle diese Compiler erlauben anscheinend die implizite Konvertierung eines Zeigers auf ein int. s=3Das würde natürlich nicht funktionieren, da Sie die Zeichenfolge zweimal an übergeben müssen printf.
Feersum

24

Java, 528 Bytes:

Eine Java-Lösung mit einem originellen Ansatz:

import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp",36);int i=0;for(byte c:b.toByteArray()){if(++i==92)System.out.print(b.toString(36));System.out.print((char)c);}}}

in lesbarer Form:

import java.math.*;
class a
{
    public static void main (String [] a)
    {
        BigInteger b=new BigInteger ("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp", 36); 
        int i=0; 
        for (byte c:b.toByteArray ())
        {
            if (++i==92) 
                System.out.print (b.toString (36)); 
            System.out.print ((char) c);
        }
    }
}

Wie funktioniert es?
Loovjo

1
@Loovjo: Ähnlich wie bei anderen Lösungen, bei denen der Code in zwei Teile geteilt und der gesamte String eingefügt wird, der den Code erneut darstellt, der gesamte Code jedoch nicht nur ein String ist, sondern als lange Zahl in Basis 36 (26 alphabetische Zeichen + 10) codiert wird Ziffern).
Benutzer unbekannt

1
Dies könnte verkürzt werden, wenn Sie setzen if(++i==92),
tuskiomi

2
@tuskiomi: Danke, verkürzt für zwei Zeichen
Benutzer unbekannt

1
@userunknown Da a*Array in Java nicht beendet wird, ist das C. Einige andere Teile zum Golfspielen :, import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("abc",36);int i=0;for(int c:b.toByteArray())System.out.printf("%s%c",++i==92?b.toString(36):"",c);}}wo abcwäre die neu berechnete magische Zahl String. In Java 8+ es ist auch möglich , sich ändern class a{public static void mainzu interface a{static void main, und in Java ist es auch möglich , 10+ zu ändern import java.math.*;und BigInteger b=new BigInteger(zu var b=new java.math.BigInteger(.
Kevin Cruijssen

23

Huhn , 7

chicken

Nein, das wird nicht direkt wiedergegeben :)


Verdammt, du hast mich geschlagen :)
Taconut

Es wird nicht wiederholt, es ist die Zeichenfolge chicken!
Erik der Outgolfer

Keine Code- / Datentrennung und daher ungültig.
CalculatorFeline

10
@CalculatorFeline Hast du die Regeln gelesen?
Timtech

1
@JoKing Ich halte das nicht für ungültig, da die Regeln der Challenge nur Quines mit der Länge Null und das Betrügen (Lesen der eigenen Quelldatei) verbieten. Das einzige, was unsachgemäße Quines verbietet, ist eine Standardlücke - mit der Ausnahme, dass Standardlücken im Allgemeinen nicht für Antworten gelten, die vor ihnen liegen.
Paprika

23

Netzhaut , 20 14 9 7 Bytes

Bevor wir anfangen, möchte ich die triviale Lösung einer Datei erwähnen, die eine einzige enthält 0. In diesem Fall wird Retina versuchen, das 0s in der leeren Eingabe zu zählen, dessen Ergebnis ebenfalls ist 0. Ich würde das aber nicht für eine richtige Quine halten.

Also hier ist eine richtige:

>\`
>\`

Probieren Sie es online!

Alternativ könnten wir ;statt verwenden >.

Erläuterung

Das Programm besteht aus einer einzelnen Ersetzung, die wir zweimal drucken.

In der ersten Zeile wird die `Konfiguration vom regulären Ausdruck getrennt, sodass der reguläre Ausdruck leer ist. Daher wird die leere Zeichenfolge (dh die nicht vorhandene Eingabe) durch die zweite Zeile wörtlich ersetzt.

Um das Ergebnis zweimal auszudrucken, verpacken wir es in zwei Ausgangsstufen. Der innere \druckt das Ergebnis mit einem nachgestellten Zeilenvorschub und der äußere mit einem nachgestellten Zeilenvorschub.> druckt es ohne einen.

Wenn Sie ein wenig mit Retina vertraut sind, fragen Sie sich möglicherweise, was mit der impliziten Ausgabe von Retina geschehen ist. Die implizite Ausgabe von Retina schließt die letzte Stufe eines Programms in eine Ausgabestufe ein. Retina tut dies jedoch nicht, wenn die Endstufe bereits eine Ausgangsstufe ist. Der Grund dafür ist, dass es in einem normalen Programm sinnvoller ist, die implizite Ausgangsstufe durch eine spezielle wie \oder ;durch ein einzelnes Byte zu ersetzen (anstatt die implizite mit dem .Flag ebenfalls entfernen zu müssen). Leider kostet uns dieses Verhalten zwei Bytes für das Quine.


20

Javascript (36 Zeichen)

(function a(){alert("("+a+")()")})()

Dies ist, AFAICT, die kürzeste Javascript-Quine, die bisher veröffentlicht wurde.


1
Das ist beeindruckend. Sie sollten erklären, wie es bei mir funktioniert 8- |
TehShrike

3
@TehShrike Hinweis: Sie können den Inhalt einer Funktion anzeigen, indem Sie sie zu einer Zeichenfolge zusammenfassen. Wenn Sie beispielsweise eine Funktion haben a, können Sie durch Aufrufen auf deren Inhalt zugreifen a.toString.
Peter Olson

7
Um pedantisch zu sein, ist dies jedoch nur dann ein Quine, wenn Ihre JavaScript-Implementierung die Funktion agenauso wie oben beschrieben stringiert . Es ist jedoch wahrscheinlich, dass die Ausgabe dieses Codes in jeder JavaScript-Implementierung eine Quine ist.
Ilmari Karonen

1
Hier ist die gleiche quine, 1 Byte kürzer: !function a(){alert("!"+a+"()")}().
Ismael Miguel

1
(a=()=>alert(($ {a})))()
Dennis C

19

GolfScript, 8 Bytes

Ich dachte immer, das kürzeste (wahre) GolfScript-Quine wäre 9 Bytes:

{'.~'}.~

Wo der nachfolgende Zeilenvorschub erforderlich ist, weil GolfScript standardmäßig einen nachfolgenden Zeilenvorschub druckt.

Aber ich habe gerade ein 8-Byte-Quine gefunden, das genau diese Zeilenvorschub-Einschränkung umgeht:

":n`":n`

Probieren Sie es online!

Der Haken ist also, dass GolfScript keinen nachgestellten Zeilenvorschub druckt, sondern den Inhalt nam Ende des Programms. Es ist nur so, dass es neinen Zeilenvorschub gibt. Daher besteht die Idee darin, diese durch die Zeichenfolge zu ersetzen ":n`"und sie dann so zu verketten, dass die Kopie auf dem Stapel mit Anführungszeichen gedruckt wird und die Kopie in nAbzügen ohne gedruckt wird.

Wie Thomas Kwa betonte, kann das 7-Byte-CJam-Quine auch an eine 8-Byte-Lösung angepasst werden:

".p"
.p

Auch hier brauchen wir den Trailing Linefeed.


6
Golfscript ist komisch.
CalculatorFeline

19

Labyrinth , 124 110 53 Bytes

Dank an Sp3000 für das Golfen mit 9 Bytes, wodurch ich weitere 7 Bytes Golf spielen konnte.

44660535853919556129637653276602333!
1
:_98
/8 %
@9_.

Probieren Sie es online!

Erläuterung

Labyrinth 101:

  • Labyrinth ist eine stapelbasierte 2D-Sprache. Der Stapel ist bodenlos und mit Nullen gefüllt, sodass das Abspringen von einem leeren Stapel kein Fehler ist.
  • Die Ausführung beginnt mit dem ersten gültigen Zeichen (hier oben links). An jeder Kreuzung, an der zwei oder mehr mögliche Pfade für den Anweisungszeiger (IP) zur Verfügung stehen, wird die Oberseite des Stapels überprüft, um zu bestimmen, wohin er als Nächstes gehen soll. Negativ ist links abbiegen, Null ist vorwärts und positiv ist rechts abbiegen.
  • Die Ziffern im Quellcode drücken nicht auf die entsprechende Zahl, sondern auf den oberen Bereich des Stapels n*10 + <digit>. Dies ermöglicht den einfachen Aufbau großer Zahlen. Verwenden Sie _, um eine neue Nummer zu beginnen , die Null drückt.
  • " sind No-Ops.

Zuerst erkläre ich eine etwas einfachere Version, die ein Byte länger, aber etwas weniger magisch ist:

395852936437949826992796242020587432!
"
:_96
/6 %
@9_.

Probieren Sie es online!

Die Hauptidee besteht darin, den Hauptteil der Quelle mit einer großen Basis in einer einzigen Zahl zu codieren. Diese Nummer kann dann einfach selbst zurückgedruckt werden, bevor sie dekodiert wird, um den Rest des Quellcodes auszudrucken. Die Dekodierung ist einfach die wiederholte Anwendung divmod base, bei der das Drucken modund Weiterarbeiten mit dem divbis zu seiner Null fortgesetzt wird .

Wenn Sie dies vermeiden {}, ist der höchste benötigte Zeichencode _(95), sodass die Basis 96 ausreicht (wenn Sie die Basis niedrig halten, ist die Zahl am Anfang kürzer). Also, was wir codieren wollen, ist Folgendes:

!
"
:_96
/6 %
@9_.

Wenn wir diese Zeichen in ihre Codepunkte umwandeln und das Ergebnis als Zahl zur Basis 96 behandeln (wobei die niedrigstwertige Ziffer der Zahl !und die höchstwertige .der Zahl entspricht , da dies die Reihenfolge ist, in der wir die Zahl zerlegen), erhalten wir

234785020242697299628949734639258593

Jetzt beginnt der Code mit einem ziemlich coolen Trick (wenn ich so sagen darf), der es uns ermöglicht, die Kodierung zurückzudrucken und eine weitere Kopie zum Dekodieren mit sehr geringem Aufwand aufzubewahren: Wir setzen die Zahl in umgekehrter Reihenfolge in den Code. Ich habe das Ergebnis mit diesem CJam-Skript berechnet. Kommen wir also zum eigentlichen Code. Hier ist der Anfang:

395852936437949826992796242020587432!
"

Die IP beginnt in der oberen linken Ecke und geht nach Osten. Während es über diese Ziffern läuft, baut es einfach diese Zahl auf dem Stapel auf. Die Zahl selbst ist völlig bedeutungslos, weil es das Gegenteil von dem ist, was wir wollen. Wenn die IP das trifft! , wird diese Nummer vom Stapel genommen und gedruckt. Das ist alles, was Sie tun müssen, um die Codierung in der Ausgabe zu reproduzieren.

Aber jetzt hat die IP eine Sackgasse erreicht. Das heißt, es dreht sich um und bewegt sich jetzt zurück nach Westen (ohne !erneut ausgeführt zu werden). Dieses Mal liest die IP bequemerweise die Nummer von hinten nach vorne, so dass dies jetzt die Nummer oben auf dem Stapel tut den Rest der Quelle codiert.

Wenn die IP nun wieder die obere linke Ecke erreicht, ist dies keine Sackgasse, da die IP eine Linkskurve machen kann und sich nun nach Süden bewegt. Das "ist ein No-Op, den wir hier brauchen, um die Nummer von der Hauptschleife des Codes zu trennen. Apropos:

...
"
:_96
/6 %
@9_.

Solange die Spitze des Stapels noch nicht Null ist, durchläuft die IP diesen ziemlich dichten Code in der folgenden Schleife:

"
>>>v
^< v
 ^<<

Oder linear angelegt:

:_96%._96/

Der Grund dafür liegt in der Steuerungsflusssemantik von Labyrinth. Wenn die aktuelle Zelle mindestens drei Nachbarn hat, wechselt die IP bei einem negativen Stack-Wert nach links, bei einer Null nach vorne und bei einem positiven Stack-Wert nach rechts. Wenn die gewählte Richtung nicht möglich ist, weil es eine Mauer gibt, nimmt die IP stattdessen die entgegengesetzte Richtung (weshalb es im Code zwei linke Umdrehungen gibt, obwohl die Oberseite des Stapels niemals negativ ist).

Der Loop-Code selbst ist eigentlich ziemlich unkompliziert (wenn man ihn so stark komprimiert, ist das der Hauptbeitrag von Sp3000):

:    # Duplicate the remaining encoding number N.
_96  # Push 96, the base.
%.   # Take modulo and print as a character.
_96  # Push 96 again.
/    # Divide N by 96 to move to the next digit.

Sobald NNull erreicht ist, ändert sich der Kontrollfluss. Jetzt möchte die IP nach dem /(dh nach Westen) geradeaus fahren , aber da ist eine Mauer. Also stattdessen, wenn sich umdreht (nach Osten), führt das 6wieder aus. Das macht die Spitze des Stapels positiv, also dreht sich die IP nach rechts (nach Süden) und führt die aus 9. Die Spitze des Stapels ist jetzt 69, aber alles, was uns interessiert, ist, dass es positiv ist. Die IP nimmt eine weitere Rechtskurve (West) und fährt auf die, @die den Code beendet.

Alles in allem ziemlich einfach.

Okay, wie können wir dieses zusätzliche Byte abschneiden? Klar, dass No-Op verschwenderisch erscheint, aber wir brauchen diese zusätzliche Zeile: Wenn die Schleife neben der Nummer wäre, würde sich die IP bereits sofort dorthin bewegen, anstatt die gesamte Nummer zu durchlaufen. Können wir mit diesem No-Op etwas Nützliches anfangen?

Im Prinzip können wir damit die letzte Ziffer zur Kodierung hinzufügen. Die Kodierung muss nicht unbedingt in der ersten Zeile stehen ... das !sorgt nur dafür, dass das, was auch immer da ist, auch dort gedruckt wird.

Es gibt jedoch einen Haken, wir können das nicht einfach tun:

95852936437949826992796242020587432!
3
:_96
/6 %
@9_.

Das Problem ist, dass wir jetzt die Zahl "in eine geändert haben 3, wodurch sich auch die tatsächliche Zahl ändert, die wir haben möchten. Und sicher endet diese Zahl nicht mit 3. Da die Anzahl vollständig durch den Code bestimmt wird, !können wir nicht viel dagegen tun.

Aber vielleicht können wir eine andere Ziffer wählen? Es ist uns egal, ob sich 3an dieser Stelle eine befindet, solange wir eine Zahl haben, die die Quelle korrekt codiert. Nun, leider ergibt keine der 10 Ziffern eine Kodierung, deren niedrigstwertige Ziffer mit der gewählten übereinstimmt. Glücklicherweise gibt es im Rest des Codes einen gewissen Spielraum, sodass wir ein paar weitere Codierungen ausprobieren können, ohne die Bytezahl zu erhöhen. Ich habe drei Möglichkeiten gefunden:

  1. Wir können ändern @zu /. In diesem Fall können wir eine beliebige Ziffer verwenden 1357und eine passende Kodierung erhalten. Dies würde jedoch bedeuten, dass das Programm dann mit einem Fehler beendet wird, der zulässig ist, aber nicht sehr sauber zu sein scheint.
  2. Leerzeichen sind nicht die einzigen "Wand" -Zeichen. Jedes unbenutzte Zeichen, insbesondere alle Buchstaben. Wenn wir einen Großbuchstaben verwenden, müssen wir nicht einmal die Basis erhöhen, um ihn aufzunehmen (da diese Codepunkte unten stehen _). 26 Auswahlmöglichkeiten bieten viele Möglichkeiten. ZB für Ajede ungerade Ziffer funktioniert. Das ist ein bisschen schöner, aber es scheint nicht besonders elegant zu sein, da Sie dort niemals einen Buchstaben in echtem Code verwenden würden.
  3. Wir können eine größere Basis verwenden. Solange wir die Basis nicht signifikant erhöhen, bleibt die Anzahl der Dezimalstellen in der Kodierung gleich (insbesondere ist jede Basis bis 104 in Ordnung, obwohl Basen über 99 tatsächlich zusätzliche Zeichen im Code selbst erfordern würden). Glücklicherweise gibt die Basis 98 eine einzige passende Lösung: Wenn wir die Ziffer verwenden 1, endet die Codierung auch mit 1. Dies ist die einzige Lösung unter den Basen 96, 97, 98, 99, also ist dies in der Tat sehr glücklich. Und so erhalten wir den Code oben in dieser Antwort.

19

Verloren , 293 262 249 Bytes

>:2+52*:6*:(84*+75*):>:::::[[[[[[[:[(52*)>::::[[[[[[:[84*+@>%?!<((((((((((([[[[[[[[[[[[[[ "
\#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\

Probieren Sie es online!

Erläuterung

Dieses gesamte Projekt war ein Auf und Ab. Ich hielt es für unmöglich und kam dann auf eine verrückte Idee, die einfach funktionieren könnte.

Warum ist ein Lost Quine so schwer?

Wie Sie vielleicht wissen, handelt es sich bei Lost um eine 2D-Programmiersprache, deren Startort und -richtung völlig zufällig sind. Dies macht das Schreiben verlorener Programme genauso schwierig wie das Schreiben von strahlungsgehärtetem Code. Sie müssen jeden möglichen Ort und jede Richtung berücksichtigen.

Davon abgesehen gibt es einige Standardmethoden, um Dinge zu tun. Hier ist zum Beispiel die Standardmethode zum Drucken einer Zeichenfolge.

>%?"Stringv"(@
^<<<<<<<<<<<<<

Am unteren Rand befindet sich ein Auflistungsstream, der die meisten ips aufnimmt und an den Startort zieht. Sobald sie die Startposition (oben links) erreicht haben, werden sie mit einer Schleife bereinigt, die alle Werte auf dem Stapel entfernt. Dann drehen Sie die Sicherheit, indem Sie die Schnur drücken und verlassen. (Sicherheit ist ein einzigartiges Konzept für Lost. Jedes Programm muss %vor dem Beenden einen Treffer erzielen. Dies verhindert, dass das Programm beim Start beendet wird.) Nun wäre meine Idee, diese Form zu einer vollwertigen Quine zu erweitern.

Als erstes musste die Schleife ein wenig überarbeitet werden, die vorhandene Schleife war spezifisch für das String-Format.

>%?!<"Stringv"(@
^<<<<<<<<<<<<<<<
^<<<<<<<<<<<<<<<

Wir müssen einen zweiten Stream hinzufügen, um die Möglichkeit zu vermeiden, !über den Stream zu springen und eine Schleife zu erstellen.

Jetzt wollen wir dies mit dem Standard-Quine-Format mischen. Da Lost sehr auf Klein basiert, habe ich mir im Grunde genommen das Klien Quine für Martin Ender geliehen .

:2+@>%?!< "
<<<<^<<<<<<
<<<<^<<<<<<

Dies druckt ganz bequem die erste Zeile des Quines. Jetzt müssen wir nur noch die Streams hart codieren. Das ist leichter gesagt als getan. Ich habe ungefähr vier verschiedene Methoden ausprobiert. Ich beschreibe nur die, die funktioniert hat.

Die Idee hier ist, Türen zu verwenden, um die gewünschte Anzahl von Pfeilen zu erhalten. Eine Tür ist eine spezielle Art von Spiegel, die sich bei jedem Treffer ändert. [reflektiert ips von links und ]von rechts. Wenn sie von einer IP von einer dieser Seiten getroffen werden, wechselt die Ausrichtung. Wir können eine Reihe dieser Türen und einen statischen Reflektor herstellen, um eine Operation wiederholt durchzuführen.

>:[[[

Wird :dreimal auftreten. Auf diese Weise <können wir eine Menge von ihnen mit weniger Bytes erstellen , wenn wir a vor der Hand auf den Stapel schieben . Wir machen 2 davon, eine für jede Zeile, und dazwischen legen wir eine neue Zeile ab, die zweite muss jedoch nur so lange bestehen, bis sie die von !uns hinzugefügte abdeckt. Alles andere kann leer bleiben und uns ein paar Bytes ersparen. Ok, jetzt müssen wir die vertikalen Pfeile zu unseren Streams hinzufügen. Hier kommt die Schlüsseloptimierung ins Spiel. Anstatt alle IPS direkt zum "Start" des Programms umzuleiten, leiten wir sie stattdessen nach ganz links um, da wir bereits wissen, dass die IPS ganz links beginnen müssenArbeit (oder wird zumindest in der endgültigen Version funktionieren) können wir auch nur die anderen IPS umleiten. Dies macht es nicht nur in Bytes billiger, ich denke, diese Optimierung macht das Quine möglich.

Es gibt jedoch immer noch einige Probleme. Das wichtigste ist, dass ips nach dem Push startet, >aber bevor wir anfangen, Kopien davon zu machen. Solche ips werden in den Kopierer eingegeben und machen eine Reihe von Kopien von 0. Dies ist schlecht, da unser Stapellöschmechanismus Nullen verwendet, um den Boden des Stapels zu bestimmen, wobei eine ganze Reihe von Nullen am Boden verbleibt. Wir müssen eine stärkere Stack-Hygienemethode hinzufügen. Da es keine echte Möglichkeit gibt, festzustellen, ob der Stapel leer ist, müssen wir einfach versuchen, so viele Gegenstände wie möglich auf dem Stapel zu zerstören. Hier verwenden wir wieder die zuvor beschriebene Türmethode. Wir werden ((((((((((([[[[[[[[[[[[[[das Ende der ersten Zeile direkt nach dem Desinfektionsprogramm hinzufügen, um die Nullen zu entfernen.

Jetzt gibt es noch ein weiteres Problem, da wir unsere Streams von oben nach links ips umgeleitet haben %und das Herunterfahren bereits die Sicherheit deaktiviert hat und vorzeitig beendet wird. Also müssen wir die Sicherheit ausschalten. Dazu fügen wir #dem Stream ein hinzu. Auf diese Weise werden die durch den Stream fließenden IP-Adressen deaktiviert, die bereits bereinigten IP-Adressen jedoch nicht. Das #muss auch in der ersten Zeile fest programmiert sein.

Hoffentlich verstehen Sie jetzt, wie das funktioniert.


: / so viele Tippfehler und fehlende Links
ASCII

17

Ja , 1165 879 606 561 540 522 498 + 7 = 505 Bytes

Benötigt das -cheatFlag, um die Definition von Aliasen zu ermöglichen.

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Probieren Sie es online!

Erläuterung

Dazu gibt es zwei Teile (wie bei den meisten Quines). Die Daten:

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212

Und der Decoder:

=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Die Daten sind lediglich eine binäre Codierung des Decoders (oder vielmehr dessen Umkehrung). Jeder 0startet ein neues Zeichen und das 1s und 2s sind die 0- und 1-bits.

Beachten Sie, dass dies 0ein Standard-Yup-Befehl ist, der eine Null drückt, während 1und 2an dieser Stelle nicht definiert sind. Wir weisen dem Befehl jedoch den gesamten Datenteil zu, %so dass das 1und 2undefiniert bleiben kann, bis %es tatsächlich verwendet wird.

Als nächstes definieren wir einige weitere Befehle:

0e-=<;
0<-=>;
:0~--=1;
1>=2;

<dekrementiert den oberen Bereich des Stapels und >inkrementiert ihn. 1(etwas unintuitiv) verdoppelt die Oberseite des Stapels. 2verdoppelt es und erhöht es dann. Dank dieser Definitionen belässt so etwas 0221111tatsächlich eine 48 (110000 in binär) auf dem Stapel.

Die verbleibenden 32 Bytes führen die eigentliche Dekodierung in zwei Teilen durch. Zuerst müssen wir den Datenstring rekonstruieren.

0%                ` Push a zero and then the data.
{                 ` For each value...
  {               `   Until that value is zero...
    >0<~{~>~<<}>  `   divmod 2. The div is the input to the next iteration,
                  `   the mod gives us the next bit.
    >>]           `   Increment twice (gives 2 or 3) and put at the bottom
                  `   of the stack.
  }
  >]              ` Increment the 0 and put it at the bottom as well.
}
$                 ` Reverse the entire stack.
{<#}              ` Decrement and print each number.

Zum Schluss geben wir die Daten erneut aus und geben jeden Wert als Zeichen aus:

%{@}

Zum späteren Nachschlagen finden Sie hier ein CJam-Skript zum Codieren der Daten.


17

Fueue , 423 Bytes

Fueue ist ein Warteschlangen-esolang in dem das laufende Programm ist die Warteschlange.

)$$4255%%1(~):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]](H-):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

Probieren Sie es online!

Wie es funktioniert

Diese Erklärung mag aus dem Ruder gelaufen sein oder auch nicht . Andererseits weiß ich nicht, wie ich es viel kürzer erklären soll, so wie ich hoffe, dass die Leute dem folgen können.

Fueue Spickzettel

Siehe esolang Wiki - Artikel für Details, einschließlich der wenigen Funktionen , die nicht in diesem Programm verwendet.

  • Das Anfangsprogramm ist der Anfangszustand der Warteschlange, der die folgenden Elemente enthalten kann:

    • Ganzzahlige Literale (nur nicht negative in der Quelle, aber negative können berechnet werden), die ausgeführt werden, geben ein Zeichen aus.
    • Durch eckige Klammern begrenzte verschachtelte Blöcke, inert (intakt erhalten, sofern keine Funktion auf sie einwirkt).
    • Funktionen, ihre Argumente sind die Elemente, die ihnen unmittelbar in der Warteschlange folgen:
      • +*/-%: ganzzahlige Arithmetik ( -ist unär, %logische Negation). Inert, wenn keine Zahlenargumente angegeben wurden.
      • ()<: Element in Klammern setzen, Klammern vom Block entfernen, letztes Element zum Block hinzufügen. Die beiden letzteren sind inert, sofern kein Block folgt.
      • ~:: tauschen, duplizieren.
      • $: copy (nimmt Nummer + Element). Inert vor Nichtzahl.
      • H: Programm anhalten.

    Beachten Sie, dass dies beim []Verschachteln ()nicht der Fall ist - letztere sind einfach separate Funktionen.

Ausführungsablaufverfolgungssyntax

Whitespace ist in Fueue optional, außer zwischen Ziffern. In den folgenden Ausführungs-Traces wird insbesondere die Programmstruktur vorgeschlagen:

  • Wenn eine Funktion ausgeführt wird, werden sie und ihre Argumente durch Leerzeichen von den umgebenden Elementen abgesetzt. Wenn einige der Argumente kompliziert sind, kann auch ein Leerzeichen dazwischen stehen.
  • Viele Ausführungsspuren sind links in einen "Delay-Blob" unterteilt, der von einem Teil rechts getrennt ist, der die wesentlichen Datenmanipulationen ausführt. Siehe nächster Abschnitt.

Geschweifte Klammern {}(in Fueue nicht verwendet) werden in den Traces verwendet, um das ganzzahlige Ergebnis mathematischer Ausdrücke darzustellen. Dies schließt negative Zahlen ein, da Fueue nur nicht negative Literale hat - -ist die Negationsfunktion.

Verschiedene metavariable Namen und ...werden zur Bezeichnung von Werten und Abkürzungen verwendet.

Verzögerungstaktik

Intuitiv durchläuft die Ausführung die Warteschlange und ändert teilweise, was sie durchläuft. Die Ergebnisse einer Funktion können erst im nächsten Zyklus erneut bearbeitet werden. Verschiedene Teile des Programms entwickeln sich effektiv parallel, solange sie nicht interagieren.

Infolgedessen ist ein Großteil des Codes der Synchronisation gewidmet, insbesondere der Verzögerung der Ausführung von Teilen des Programms bis zum richtigen Zeitpunkt. Es gibt viele Möglichkeiten, um Golf zu spielen, was dazu führt, dass Teile zu unlesbaren Blobs werden, die nur durch zyklisches Nachverfolgen ihrer Ausführung verstanden werden können.

Diese Taktiken werden im Folgenden nicht immer einzeln erwähnt:

  • )[A]Verzögerungen Afür einen Zyklus. (Wahrscheinlich die einfachste und am besten lesbare Methode.)
  • ~eftauscht die Elemente aus eund fverzögert damit auch deren Ausführung. (Wahrscheinlich die am wenigsten lesbare, bei geringfügigen Verzögerungen jedoch häufig die kürzeste.)
  • $1everzögert ein einzelnes Element e.
  • -und %sind nützlich zum Verzögern von Zahlen (letztere für 0und 1.)
  • Wenn Sie mehrere gleiche Elemente in einer Reihe verzögern :oder $sie aus einem einzigen erstellen möchten.
  • (nUmwicklungen nin Klammern, die später nach Belieben entfernt werden können. Dies ist besonders wichtig für numerische Berechnungen, da Zahlen zu instabil sind, um überhaupt kopiert zu werden, ohne sie zuerst in einen Block zu setzen.

Gesamtstruktur

Der Rest der Erklärung ist in sieben Teile unterteilt, die sich jeweils auf einen Abschnitt des laufenden Programms beziehen. Die größeren Zyklen, nach denen sich die meisten von ihnen wiederholen, werden als "Iterationen" bezeichnet, um sie von den "Zyklen" einzelner Durchläufe durch die gesamte Warteschlange zu unterscheiden.

So teilt sich das ursprüngliche Programm auf:

A:  )$$4255%%1(~
B:  ):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
C:  
D:  (H-
E:  
F:  
G:  ):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

Die große Zahl am Ende des Programms codiert den Rest in umgekehrter Reihenfolge, zwei Ziffern pro Zeichen, wobei 30 von jedem ASCII-Wert abgezogen werden (also z . B. 10a (.).

Auf einer höheren Ebene können Sie sich die Daten in diesem Programm (beginnend mit dem Bignum) als von rechts nach links fließend vorstellen, die Steuerung jedoch als von links nach rechts fließend. Auf einer niedrigeren Ebene verwirrt Fueue jedoch ständig die Unterscheidung zwischen Code und Daten.

  • Abschnitt G dekodiert das Bignum in ASCII-Ziffern (z. B. Ziffer 0als Ganzzahl 48), wobei die niedrigstwertigen Ziffern zuerst abgespalten werden. Alle 15 Zyklen wird eine Ziffer ausgegeben.
  • Abschnitt F enthält die erzeugten Ziffern-ASCII-Werte (jeweils innerhalb eines Blocks), bis Abschnitt E sie verbrauchen kann.
  • In Abschnitt E werden die produzierten Ziffern zu je zwei verarbeitet, zu Blöcken des Formulars gepaart [x[y]]und auch die codierten Zeichen jedes Paares gedruckt.
  • Abschnitt D besteht aus einem tief verschachtelten Block, der nach und nach aus den [x[y]]Blöcken so aufgebaut wird, dass alle Ziffern gedruckt und anschließend das gesamte Programm angehalten werden können.
  • Abschnitt C behandelt den Bau von Abschnitt D und erstellt auch Abschnitt E neu.
  • Abschnitt B erstellt Abschnitt C sowie sich selbst alle 30 Zyklen neu.
  • Abschnitt A zählt die Zyklen bis zur letzten Iteration der anderen Abschnitte herunter. Dann bricht es Abschnitt B ab und führt Abschnitt D aus.

Abschnitt a

Abschnitt A behandelt die Planung des Programmendes. Es dauert 4258 Zyklen, um sich auf eine einzige Swap-Funktion zu reduzieren ~, die dann eine Anpassung an Abschnitt B vornimmt, der seine Hauptschleife stoppt und stattdessen Abschnitt D ausführt.

)$ $4255% %1 (~
)$%%%...%% %0 [~]
)$%%%...% %1 [~]
⋮
)$ %0 [~]
) $1[~]
)[~]
~
  • Eine $Funktion erstellt 4255 Kopien der folgenden Elemente, %während (die ~in eckigen Klammern eingeschlossen sind.
  • In jedem Zyklus wird der letzte %verwendet, um die folgende Zahl zwischen 0und umzuschalten 1.
  • Wenn alle %s aufgebraucht sind, $1wird 1 Kopie der [~](effektiv eine NOP) erstellt, und beim nächsten Zyklus werden )die Klammern entfernt.

Abschnitt b

In Abschnitt B wird sowohl die Selbstregenerierung als auch eine neue Iteration von Abschnitt C alle 30 Zyklen durchgeführt.

) : [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]            [BkB]
)$ $24%     %0  :<  [~:)~)]    ~ [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<] [BkB]
)$ %...%%% %1   < < [~:)~)] [BkB]   [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...%% %0      < [~:)~)[BkB]] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...% %1         [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
⋮
) $1 [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                    (1)
~:) ~)[BkB]                 [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
) : [BkB]                 ) [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]      (2)
) [BkB] [BkB]               $11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<
  • A :dupliziert den folgenden großen Block (eine Kopie wird als abgekürzt [BkB]) und )entfernt dann die Klammern von der ersten Kopie.
  • $$24%%0 legt einen Countdown an, der dem in Abschnitt A ähnelt.
  • Während dies abwärts zählt, :<wird es zu <<einem und ~tauscht zwei der Blöcke aus, wobei der Code für einen neuen Abschnitt C zuletzt platziert wird.
  • Die beiden <Funktionen packen die beiden letzten Blöcke in den ersten - dies ist in normalen Iterationen überflüssig, ermöglicht jedoch, dass der ~Ab-Abschnitt A am Ende seine Arbeit erledigt.
  • (1) Wenn der Countdown beendet ist, werden )die äußeren Klammern entfernt. Next ~:)wird zu ):und ~)tauscht a )an den Anfang des Abschnitts C-Codes.
  • (2) Abschnitt B befindet sich nun wieder in seinem Anfangszyklus, während a )gerade dabei ist, die Klammern zu entfernen, um eine neue Iteration von Abschnitt C auszuführen.

In der letzten Iteration erscheint ~ab Abschnitt A unter Punkt (1) oben:

~ ) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                  (1)
[~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]              )

Die ~vertauscht den )Block in Abschnitt C, wodurch verhindert wird, dass Abschnitt B erneut ausgeführt wird.

Abschnitt C

In Abschnitt C werden neue Ziffernpaare in den Block von Abschnitt D eingefügt und neue Iterationen von Abschnitt E erstellt.

Das Folgende zeigt eine typische Iteration mit xund die yDarstellung der ASCII-Codes der Ziffern. In der allerersten Iteration sind die eingehenden "D" - und "E" -Elemente die ersten [H]und -stattdessen, da kein vorheriger Abschnitt E ausgeführt wurde, um Ziffernzeichenpaare zu erzeugen.

C                                               D             E
$11~ )  ~<[[+$4--498+*-:~-10)):])<~]  [)))~]  < [)))~[...]]   [x[y]]
~~~ ~~~ ~~~ ~~) [[+$4--498+*-:~-10)):])<~]  < [)))~] [)))~[...][x[y]]]
~~~ ~~~     )  ~ [[+$4--498+*-:~-10)):])<~] [)))~[)))~[...][x[y]]]]
~~~       ~ )   [)))~[....]]                                  [[+$4--498+*-:~-10)):])<~]
                                              ~~[)))~[....]] )[[+$4--498+*-:~-10)):])<~]
                                                [)))~[....]]  ~[+$4--498+*-:~-10)):])<~
  • Dabei wird eine andere Synchronisationsmethode verwendet, die ich für diese Antwort entdeckt habe. Wenn Sie mehrere Swap-Funktionen ~in einer Reihe haben, wird die Reihe in jedem Zyklus auf ungefähr 2/3 verkleinert (da einer ~zwei aufeinanderfolgende tauscht), aber gelegentlich mit einem Rest von ~s, das Verwüstungen anrichtet, manipuliert sorgfältig das Folgende.
  • $11~erzeugt eine solche Reihe. Der nächste ~tauscht a <über den folgenden Block. Ein anderer <fügt am Ende einen neuen Ziffernpaarblock (Ziffern x und y als ASCII-Codes) in den Abschnitt D-Block ein.
  • Im nächsten Zyklus hat die ~Zeile einen ~~Rest, der a ~über Folgendes vertauscht ). Der andere <fügt Abschnitt D an einen [)))~]Block an.
  • Als nächstes ~tauscht der Swap selbst den folgenden Block mit neuem Abschnitt-E-Code über den Abschnitt-D-Block. Dann ~tauscht ein neuer Rest ein )Kreuz aus, und schließlich tauscht der letzte ~~in der ~Reihe eines von ihnen in Abschnitt E aus, gerade als der )seine Klammern entfernt hat.

In der letzten Iteration haben die Abschnitte A die Abschnitte B und C ~vertauscht. )Abschnitt C ist jedoch so kurzlebig, dass er bereits verschwunden ist und )am Anfang von Abschnitt D endet.

Abschnitt D

In Abschnitt D wird die letzte große Zahl gedruckt und das Programm angehalten. Während des größten Teils des Programmablaufs handelt es sich um einen inerten Block, in dem die Abschnitte B – G beim Bauen zusammenarbeiten.

    (H -
    [H]-
    ⋮
    [)))~[H-]]                  After one iteration of section C
    ⋮
    [)))~[)))~[H-][49[49]]]]    Second iteration, after E has also run
    ⋮
)   [)))~[...]]     [49[48]]    Final printing starts as ) is swapped in
    ))) ~[...][49[48]]
    )) )[49[48]] [...]
    )) 49 [48][...]             Print first 1
    ) )[48] [...]
    ) 48 [...]                  Print 0
    )[...]                      Recurse to inner block
    ...
    ⋮
    )[H-]                       Innermost block reached
    H -                         Program halts
  • Im ersten Zyklus des Programms wird (die Haltefunktion Hin eckige Klammern gesetzt. A -folgt, es wird als Dummy-Element für die erste Iteration anstelle eines Ziffernpaares verwendet.
  • Das erste reelle Ziffernpaar, das einbezogen wird [49[49]], entspricht dem Finale 11in der Ziffer.
  • Das allerletzte digit Paar [49[48]](entsprechend dem 10am Anfang der Nummer) nicht tatsächlich in den Block eingearbeitet, aber dies macht keinen Unterschied , wie )[A[B]]und )[A][B]äquivalent ist, in beiden Dreh A[B].

Nach der letzten Iteration kommt der )von Abschnitt B nach rechts getauschte Block an und der Block von Abschnitt D wird entsperrt. Am )))~Anfang jedes Unterblocks wird sichergestellt, dass alle Teile in der richtigen Reihenfolge ausgeführt werden. Schließlich enthält der innerste Block ein HAnhalten des Programms.

Abschnitt E

Abschnitt E behandelt das Kombinieren von ASCII-Ziffernpaaren, die von Abschnitt G erzeugt wurden, und beide drucken das entsprechende codierte Zeichen und senden einen Block mit dem kombinierten Paar nach links an die Abschnitte C und D.

Wiederum zeigt das Folgende eine typische Iteration mit xund yDarstellung der ASCII-Codes der Ziffern.

E                                                   F
~ [+$4--498+*-:~-10)):] )              <  ~         [y] [x]
) [+$4--498+*-:~-10)):]                   < [x] [y]
+ $4-  - 498  +*- :~ -10 ) )              : [x[y]]
+---  -{-498} +*- ~~{-10} )       ) [x[y]]  [x[y]]
+--    - 498  +*   -{-10}       ~ ) x  [y]  [x[y]]
+-    -{-498} +               * 10 x  )[y]  [x[y]]
+      - 498                    + {10*x} y  [x[y]]
                         + {-498} {10*x+y}  [x[y]]
{10*x+y-498}  [x[y]]
[x[y]]
  • Die eingehenden Ziffernblöcke werden vertauscht, dann wird der y-Block an den x-Block angehängt und der gesamte Paarblock kopiert. Eine Kopie bleibt bis zum Ende für die Abschnitte C und D.
  • Die andere Kopie wird erneut entsperrt, und dann wird eine Folge von arithmetischen Funktionen angewendet, um 10*x+y-498den ASCII-Wert des codierten Zeichens zu berechnen . 498 = 10*48+48-30, Die 48rückgängig gemacht werden s die ASCII - Kodierung xund ywährend der 30Verschiebungen der Codierung von 00–99zu 30–129, die alle druckbaren ASCII enthält.
  • Die resultierende Zahl wird dann ausgeführt, wodurch das Zeichen gedruckt wird.

Abschnitt F

Abschnitt F besteht aus inerten Blöcken, die ASCII-Zifferncodes enthalten. Für den größten Teil des Programmablaufs gibt es hier höchstens zwei, da Abschnitt E sie mit derselben Geschwindigkeit verbraucht, mit der G sie erzeugt. In der letzten Druckphase 0sammeln sich hier jedoch einige redundante Ziffern.

[y] [x] ...

Abschnitt G

Abschnitt G behandelt das Aufteilen der großen Zahl am Ende des Programms, wobei die niedrigstwertigen Ziffern zuerst angezeigt werden, und das Senden von Blöcken mit ihren ASCII-Codes nach links an die anderen Abschnitte.

Da es keine Unterbrechungsprüfung gibt, werden tatsächlich weiterhin 0Ziffern erzeugt, wenn die Zahl auf 0 gesunken ist, bis Abschnitt D das gesamte Programm mit der HFunktion anhält .

[BkG] Kürzt eine Kopie des großen Startcode-Blocks ab, der zur Selbstreplikation verwendet wird, um neue Iterationen zu starten.

Initialisierung in den ersten Zyklen:

) :~  : [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  ( 106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
)  ~ ~ [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  [BkG] [10...11]
) [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]     ~ [BkG] [10...11]
) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]       ~ : [10...11]  [BkG]

Typische Iteration, Nbezeichnet die zu teilende Zahl:

) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]        ~ : [N]  [BkG]
) :~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+ :5 )         : [N]  : [BkG]
)  ~ ~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]  +5 5     ) [N]  [N] [BkG] [BkG]
) [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]               ~ 10 N  [N] [BkG] [BkG]
) ~:~  ~ ( [:~)*[):~[$1(+48]):~+]-:~~)10)~~]               / N 10  [N] [BkG] [BkG]
)  ~ : [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                 ( {N/10}  [N] [BkG] [BkG]
) [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                    : [{N/10}]  [N] [BkG] [BkG]
:~ )*[):~[$1(+48]):~+]- :~ ~)10 )           ~ ~ [{N/10}]  [{N/10}] [N] [BkG] [BkG]
~~) *[):~[$1(+48]):~+]- ~~10 )             ) [{N/10}]  ~ [{N/10}] [N]  [BkG] [BkG]
)  ~ * [):~[$1(+48]):~+]  -10            ~ ) {N/10}  [N] [{N/10}] [BkG] [BkG]
) [):~[$1(+48]):~+]               * {-10} {N/10}  ) [N]  [{N/10}] [BkG] [BkG]
) :~ [$1(+48]) :~                 + {-10*(N/10)} N  [{N/10}] [BkG] [BkG]
)  ~ ~ [$1(+48]  )                 ~ ~ {N%10}  [{N/10}] [BkG] [BkG]
) [$1(+48]                 ~ ) {N%10}  ~ [{N/10}] [BkG]  [BkG]
$1(                     + 48 {N%10}    ) [BkG]  [{N/10}] [BkG]
                        ( {48+N%10}   BkG [{N/10}] [BkG]            New iteration starts
                        [{48+N%10}]   ....
  • Der Delay-Blob ist hier besonders haarig. Allerdings ist der einzige neue Verzögerungs Trick zu verwenden , +:5statt --10eine Verzögerung 10zwei Zyklen. Leider wurde nur einer der 10s im Programm dadurch geholfen.
  • Die Blöcke [N]und [BkG]werden dupliziert, dann wird eine Kopie von Ndurch geteilt 10.
  • [{N/10}]dupliziert wird, werden mehr arithmetische Funktionen verwendet, um den ASCII-Code der letzten Ziffer von Nas zu berechnen 48+((-10)*(N/10)+N). Der Block mit diesem ASCII-Code bleibt für Abschnitt F übrig.
  • Die andere Kopie von [{N/10}]wird zwischen den [BkG]Blöcken ausgetauscht , um den Start einer neuen Iteration einzurichten.

Bonus Quine (540 Bytes)

)$$3371%%1[~!~~!)!]):[)$$20%%0[):]~)~~[)$$12%%0[<$$7%~~0):~[+----48+*-~~10))]<]<~!:~)~~[40~[:~))~:~[)~(~~/[+--48):]~10]+30])):]]][)[H]](11(06(06(21(21(25(19(07(07(19(61(96(03(96(96(03(11(03(63(11(28(61(11(06(06(20(18(07(07(18(61(11(28(63(96(11(96(96(61(11(06(06(19(20(07(07(18(61(30(06(06(25(07(96(96(18(11(28(96(61(13(15(15(15(15(22(26(13(12(15(96(96(19(18(11(11(63(30(63(30(96(03(28(96(11(96(96(61(22(18(96(61(28(96(11(11(96(28(96(61(11(96(10(96(96(17(61(13(15(15(22(26(11(28(63(96(19(18(63(13(21(18(63(11(11(28(63(63(63(61(11(61(42(63(63

Probieren Sie es online!

Da ich mir nicht sicher war, welche Methode am kürzesten ist, habe ich zuerst versucht, Zeichen als zweistellige Zahlen zu codieren, die durch (s getrennt sind . Der Kerncode ist etwas kürzer, aber die 50% größere Datendarstellung macht das wieder wett. Nicht so golfen wie der andere, da ich aufhörte, als mir klar wurde, dass es nicht besser werden würde. Es hat einen Vorteil: Es erfordert keine Implementierung mit Bignum-Unterstützung.

Die Gesamtstruktur ist der Hauptstruktur etwas ähnlich. Abschnitt G fehlt, da die Datendarstellung Abschnitt F direkt ausfüllt. Abschnitt E muss jedoch eine ähnliche Divmod-Berechnung durchführen, um die Ziffern der zweistelligen Zahlen zu rekonstruieren.


1
Sie sollten die Erklärung XD
VFD

1
)$n[)](ist ein Byte kürzer für den Verzögerungszähler.
Jimmy23013

15

Gelee, 3 Bytes

”ṘṘ

Probieren Sie es online!

Nachprüfung

$ echo $LANG
en_US
$ xxd -g 1 quine.jelly
0000000: ff cc cc                                         ...
$ ./jelly f quine.jelly | xxd -g 1
0000000: ff cc cc                                         ...

Wie es funktioniert

”ṘṘ    Main link. No input.

”Ṙ     Set the return value to the character 'Ṙ'.
  Ṙ    Print a string representation of the return value.
       This prints: ”Ṙ
       (implicit) Print the return value.
       This prints: Ṙ

Welche Version des Interpreters verwendet dieser? Wenn ich es teste, wird es in UTF-8 ausgegeben, obwohl sich die Eingabe in Jellys Codepage befindet (und die Änderung der Codierung würde dazu führen, dass es kein Quine ist).

1
Die Codierung der Ausgabe hängt von den Einstellungen Ihres Terminals ab: Wenn UTF-x eingestellt ist, wird dies verwendet. Wenn es auf etwas anderes eingestellt ist, wird Jellys Codepage verwendet. Unter Linux LANG=en_USgelingt genau das. tio.run/nexus/bash#@@/…
Dennis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.