Schreiben Sie den längsten iterierenden Quine-Zeitraum, der von 500 Bytes begrenzt wird

16

Ihre Aufgabe ist es, das Quine mit der längsten Iterationsdauer zu erstellen , wobei die Länge jedes Programms in der Sequenz durch 500 Bytes begrenzt ist.

Das heißt, wenn Sie die folgenden Schritte wiederholen:

  1. Beginnen Sie mit Ihrem ersten Programm
  2. Führen Sie das aktuelle Programm aus
  3. Fahren Sie mit Schritt 2 fort

Sie kehren schließlich zu Ihrem ursprünglichen Programm zurück. Die Anzahl der Programme im Zyklus ist Ihre Punktzahl, die Sie maximieren möchten.

Keines der Programme kann Fehler auslösen. Jedes Programm muss auf die gleiche Weise ausgeführt werden (z. B. keine unterschiedlichen Versionen, Implementierungen, Compileroptionen, Plattformen usw.) (BEARBEITEN: Ja, ein externer Status wie der eines Pseudozufallszahlengenerators wurde in den letzten eingeschlossen Anweisung. Der externe Zustand muss nach jedem Lauf "zurückgesetzt" werden. Wenn Sie echte Zufallszahlen verwenden, wird der ungünstigste Fall angenommen.)

Was diese Herausforderung von der am längsten wiederholten Quine unterscheidet (außer 100 gegenüber 500), ist, dass jedes Programm im Zyklus auch 500 Byte oder weniger umfassen muss. Dies bedeutet, dass der längste mögliche Zyklus (256 ^ 501 - 1) / 255 oder weniger beträgt. Das ist natürlich eine große Zahl, aber nicht so groß, wie viel Code für die Berechnung benötigt wird. Bei der Herausforderung geht es also darum, so viele der (256 ^ 501 - 1) / 255-Möglichkeiten wie möglich zu nutzen, und nicht um eine geschäftige Biber-Herausforderung.

Die Programme dürfen nicht auf ihren eigenen Quellcode zugreifen. Ein leeres Programm ist jedoch zulässig, wenn Sie möchten (solange Sie die anderen Regeln befolgen).

Da es schwierig wäre, die Programme manuell zu überprüfen, können Sie die Punktzahl mit theoretischen Methoden ermitteln. Sie müssen Ihrem Programm eine Erläuterung der Punktzahl und der Richtigkeit beifügen. Wenn Sie die Punktzahl nicht herausfinden können, können Sie stattdessen eine Untergrenze der Anzahl der Programme im Zyklus als Defacto-Punktzahl verwenden. Sie können dies aktualisieren, wenn Sie bessere Untergrenzen finden oder wenn Sie die genaue tatsächliche Punktzahl finden.

Dies ist eine , daher gewinnt die höchste Punktzahl!

BEARBEITEN: Es wird empfohlen, dass Sie schreiben, was Ihre Partitur in wissenschaftlicher Notation ist, damit die Antworten leichter vergleichbar sind. Es ist vollkommen in Ordnung, auch andere Formen der Partitur zu haben, insbesondere wenn diese klarer mit Ihrem Programm verbunden sind. Die Leser werden außerdem aufgefordert, frühere Antworten zu bearbeiten, um dies zu berücksichtigen.

PyRulez
quelle
2
"Der längste mögliche Zyklus ist (256 ^ 501 - 1) / 255 oder weniger" --- Dies muss nicht unbedingt zutreffen, da das Programm möglicherweise mehrmals denselben Status durchläuft, bevor es zum Original zurückkehrt, wenn es ein externes Objekt manipuliert ( wie der RNG-Zustand oder Startwert)
JDL
2
@JDL, das sollte gegen die Regeln verstoßen, IMHO - wenn es den Status an einer anderen Stelle als im Quellcode speichert, dann ist es kein ordentliches iterierendes Quine.
Nathaniel
1
@ Nathaniel Ich würde es nicht anderswo als Speicherzustand einstufen. Es werden einfach Einstiegspunkte verwendet, die ein gültiger Teil der Programmiersprache sind, in der es implementiert ist. Alles, was eine andere Funktion in der Programmiersprache aufruft, greift möglicherweise auf Zustände zu, die sich außerhalb befinden einen eigenen Quellcode.
JDL
1
@JDL nein, das sind verschiedene Dinge. Jedes Programm , in jeder Sprache hat offensichtlich auf Dinge verlassen , die außerhalb des Quellcodes implementiert sind, aber die Speicherung Zustand außerhalb des Quellcodes ist anders. Dies würde bedeuten, dass die Ausgabe des Programms keine deterministische Funktion des Quellcodes ist, sondern von einem anderen externen Kontext abhängt, der durch vorherige Läufe geändert wurde. Das sollte bei einer Quine-Challenge nicht erlaubt sein, und die Aussage des OP über die maximale Zykluslänge deutet darauf hin, dass dies hier nicht erlaubt sein sollte.
Nathaniel
3
@JDL Wie Sie sicher wissen, speichert der Befehlszeiger in einer deterministischen Sprache den Status nur während der Ausführung eines Programms und nicht zwischen dessen Aufrufen. Ihr Beispiel mit 5 Zuständen ist nicht möglich, wenn die Ausgabe des Programms eine deterministische Funktion der Quelle ist.
Nathaniel

Antworten:

12

Perl 6 , 1263988.86×10835 Iterationen

$!=Q~~;<say "\$!=Q~{chrs(my@a=[R,] polymod :126[$!.ords]+1: 126 xx*)x?(@a-399)}~;<$_>~~.EVAL">~~.EVAL

Probieren Sie es online!

Dies durchläuft alle möglichen Kombinationen der ersten 126 Bytes mit einer Länge von 398 und darunter (mit Ausnahme von Zeichenfolgen mit führenden NUL-Bytes). Wenn Sie sehen möchten, dass es tatsächlich zur ersten Iteration zurückkehrt, können Sie die Länge auf 1 reduzieren, indem Sie das Limit wie folgt ändern .

Erläuterung:

Bei jeder Iteration wird die Zeichenfolge inkrementiert, die in der Form der Basis 126 gespeichert ist, und anschließend wieder in die Basis 126 konvertiert. Dies geschieht so lange, bis eine Zeichenfolge mit der Länge 399 erreicht wird, und anschließend wird die Zeichenfolge zurückgesetzt, um sie wieder zu leeren. Stellen Sie sich die Zahl stattdessen mit zehn Bytes vor, wenn Sie Probleme bei der Konzeption haben. Erhöhen Sie ab 0bis zu 4 Stellen 1000und setzen Sie sie zurück. Dies sind 104-1 Iterationen (einschließlich 0oder leere Zeichenfolge in meinem Programm).

$!=Q~~;         # Start with an empty string
< ... >~~.EVAL  # Set a string to $_ and EVAL it
  say "\$!=Q~{...}~;<$_>~~.EVAL"   # Print the program with the string replaced by
                       :126[$!.ords]   # The string converted from base 126
                                    +1 # Incremented
          [R,] polymod                : 126 xx*  # Back to base 126
chrs(                                )  # Back to a string
     my@a=                            x?(@a-399)  # Only if it isn't 399 characters
Scherzen
quelle
1
Wow, du hast das wirklich schnell gemacht, ich bin fast fertig mit meinem, aber ich werde es wahrscheinlich morgen beenden (meins wird in Gol sein> <>)
KrystosTheOverlord
Diese Berechnung deutet darauf hin, dass Sie Ihre Punktzahl deutlich überbewertet haben. Der Zähler gibt an, wie viele Zeichenfolgen mit der Länge 397 126 Symbole verwenden. (Ich musste den Bruch in die Summe verteilen, da Wolfram Alpha seltsam wirkte.)
PyRulez
@PyRulez Ich denke, meine Nummer ist korrekt, da es sich im Grunde genommen um eine 126er Basisnummer mit bis zu 399 Stellen handelt ... Ich denke, meine Erklärung war falsch
Jo King,
@JoKing ah ja, ich denke die Erklärung war das Problem. Sie haben 397 in 398 geändert, wodurch Ihre Punktzahl nicht mehr überschätzt wird. Sie könnten es unterschätzen (da Sie nur Zeichenfolgen mit einer Länge von genau 398 in die Partitur aufgenommen haben), aber das ist in Ordnung.
PyRulez
2

Runische Enchantments , 64654 106 ; 122 387 -1 ≈ 2,638 × 10 807 Iterationen

"3X4+kSq'ƃZ,r{1?{1[:1Z%1+:a=+:d=+:3X4+=+:6X2+=+:'€(c*?~1-1kq}͍f1+0Bl1=6*?S1-Skql͗2=4*?{͍]}B͍l1=6*?kS1-Sq]}@

Probieren Sie es online!

Warnung: Das wird falsch angezeigt, es sollte `` (0x80) sein.

Verwenden Sie ͍anstelle des Stapels eine Zeichenfolge und die mit geänderten Stapeloperatoren, um eine Zeichenfolge anstelle des Stapels zu ändern (siehe vorherige Überarbeitung). Als solches ist jedes Zeichen auf 1 Byte begrenzt (Bereich 0-127, abzüglich der problematischen Zeichen), jedoch mit mehr als 3-mal so vielen Zeichen (aufgrund der geringeren Verarbeitungsrate, da Unicode-Zeichen nicht übersprungen werden müssen) neben einigen anderen Byteeinsparungen) wird eine höhere Anzahl von Iterationen erzielt.

Wenn die Codierung als echter Big-Endian zulässig ist ( dh , wenn Bytewerte über 127 vorliegen, ohne dass 0x00Bytes dazwischengeschoben werden), kann dies zu Iterationen von 251 387 -1 ≈ 4.717 × 10 928 führen . Die lateinische Kodierung von TIO verhindert dies jedoch, wie Erik der Outgolfer in seiner Antwort auf Python 2 festgestellt hat. Ich müsste überprüfen, ob es lokal funktioniert, bevor ich diese Punktzahl beanspruche.

Sollte der Lage sein , zu ersetzen , f1+0Bmit '0B(es gibt eine unprinting 0x16dort), aber es kämpfte mich (Dinge wollte nicht Zweig / Überspringen / Rückkehr richtig), so dass ich es allein gelassen. Dies würde die Big-Endian-Struktur von 387 auf 388 erhöhen.

Draco18s
quelle
1

DOS COM, 49 Bytes, Periode 2 ^ 3608

00000000  be 31 01 89 f7 b9 f4 02  f9 ac 14 00 aa 39 ce 72  |.1...........9.r|
00000010  f8 31 c9 b4 3c ba 2b 01  cd 21 89 c3 b4 40 b9 f4  |.1..<.+..!...@..|
00000020  01 ba 00 01 cd 21 b4 3e  cd 21 c3 71 2e 63 6f 6d  |.....!.>.!.q.com|
00000030  00                                                |.|

Originalbaugruppe zum Erstellen:

 BITS 16
 ORG 0100h
   mov si, l
   mov di, si
   mov cx, 500 + 0100h
   stc
n: lodsb
   adc al, 0
   stosb
   cmp si, cx
   jb n
   xor cx, cx
   mov ah, 3ch
   mov dx, f
   int 21h
   mov bx, ax
   mov ah, 40h
   mov cx, 500
   mov dx, 0100h
   int 21h
   mov ah, 3eh
   int 21h
   ret
f: db "q.com", 0
l: db 0

Dieses kleine Juwel schreibt die nächste Phase an q.com und nicht an die Standardausgabe, da das Terminal keine Nullen und andere Dinge verarbeiten kann. Die Root-Quine-Technik entspricht der Stringifizierung, und der Nutzlastraum wird als 3608-Bit-Zähler verwendet. Aufgrund der Funktionsweise von DOS enthält der Anfangszustand des Zählers Ablagerungen von allem, was sich vor seiner ersten Ausführung im Speicher befand.

Die ursprüngliche 49-Byte-Eingabe ist nicht erreichbar. Wenn Sie diese also mit 500 Byte bewerten möchten, fahren Sie fort.

Joshua
quelle
1

C # (Visual C # Interactive Compiler) , Flags: /u:System.Numerics.BigIntegerund/r:System.Numerics

Prüfungsergebnis: 10 332

Vielen Dank an JoKing, der meine Punktzahl von 10 255 * 2 - 1 auf jetzt erhöht hat !

var i=Parse("0");var s="var i=Parse({0}{2}{0});var s={0}{1}{0};Write(s,(char)34,s,(++i).ToString().Length<333?i:0);";Write(s,(char)34,s,(++i).ToString().Length<333?i:0);

Probieren Sie es online!

Erläuterung

Inkrementiert eine BigInteger-Zahl bei jeder Iteration, bis ihre Länge zu groß wird. In diesem Fall kehren wir sofort zum ursprünglichen Quine zurück.

//The BigInteger that will be incremented
var i=Parse("0");
//The string that encodes the quine
var s="var i=Parse({0}{2}{0});var s={0}{1}{0};Write(s,(char)34,s,(++i).ToString().Length<333?i:0);";
//Print out the string, with every {0} replaced with quotes and the {1} replaced with the original string
Write(s,(char)34,s,
//And the {2} is replaced to the BigInteger+1 if the BigInteger wouldn't be too long, else 0
(++i).ToString().Length<333?i:0);
Verkörperung der Ignoranz
quelle
1

252219

#coding=L1
s=""""""
for i in range(220-len(s.lstrip("ÿ")))[:219]:s=s[:i]+chr(ord(s[i])%255-~(s[i]in"!$&"))+s[i+1:]
S='#coding=L1\ns="""%s"""\nfor i in range(220-len(s.lstrip("\xff")))[:219]:s=s[:i]+chr(ord(s[i])%%%%255-~(s[i]in"!$&"))+s[i+1:]\nS=%%r;print S%%%%s%%%%S';print S%s%S

Beachten Sie, dass eine nachgestellte Zeile vorhanden ist. Es könnte oben entfernt werden, wenn der Syntax-Textmarker seinen Weg erzwingt.

Leider können Sie dieses Programm nicht in TIO ausführen, da es in Latin-1 codiert ist.

Oben, senthält 219 0x01 Bytes. Nachdem das Programm ausgeführt wurde, wird die Quelle mit Ausnahme eines Unterschieds sausgegeben : Wurde wie eine Big-Endian-Zahl zur Basis 252 inkrementiert, sodass das Zeichen ganz links auf 0x02 "inkrementiert" wurde. Die Bytes 0x00, 0x22, 0x25 und 0x5C werden vermieden. Wenn also ein Zeichen der Zeichenfolge nach der Inkrementierung eines dieser Zeichen wird, wird das Zeichen selbst erneut inkrementiert.

  • 0x00 (null): Eine Python-Quelldatei darf keine Nullzeichen enthalten.
  • 0x22 ( "): Es besteht die Gefahr, dass sich drei 0x22-Bytes in einer Reihe bilden """oder das letzte Zeichen der Zeichenfolge wird ", sodass die Zeichenfolge vorzeitig geschlossen wird.
  • 0x25 ( %): printf artige Zeichenfolge Formatierung vor Beendigung des quine Skeletts verwendet wird, so dass ein %nicht benachbart zu einem anderen %in swird zu Problemen führen. Leider ist es nicht möglich, die Formatierung neu zu ordnen, um diese Einschränkung zu vermeiden.
  • 0x5C ( \): Es besteht die Möglichkeit, dass das \Zeichen nicht wörtlich, sondern als Escape-Zeichen in der Zeichenfolge verwendet wird, sodass es vermieden wird.

Daher sind 252 von 256 Bytes verwendbar. Wenn es s219 0xFF ( ÿ) Bytes enthält, wird es einfach auf 219 0x01 Bytes zurückgesetzt, wodurch der Zyklus abgeschlossen wird.

252219

252219=8067118401622543607173815381864126969021321378412714150085501148172081568355283332551767558738710128769977220628694979838777041634307806013053042518663967641130129748108465109552157004184441957823830340121790768004370530578658229253323149648902557120331892465175873053680188287802536817909195292338112618632542000472094347226540339409672851252596442228662174845397731175044304251123874046626291460659909127172435776359148724655575878680270692451120531744950544969860952702932354413767504109600742385916705785109741289800204288

Erik der Outgolfer
quelle
1

2512262.1×10542

  • 251 39 Abhängigkeit von entferntText
  • 251 122 Golf-Inkrementierungsfunktion
  • 251 128 kombinierte Präfix- und Suffix-Quellzeichenfolgen
  • 251 188 entfernte Abhängigkeit vonGast.GenLibTest

Präsentiert im xxd-Format wegen nicht druckbarer / ungültiger UTF-8:

00000000: 6d6f 6475 6c65 2071 3b69 6d70 6f72 7420  module q;import 
00000010: 5374 6445 6e76 3b53 7461 7274 3d28 7325  StdEnv;Start=(s%
00000020: 2830 2c34 3129 2c3f 5b27 0101 0101 0101  (0,41),?['......
00000030: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000040: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000050: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000060: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000070: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000080: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000090: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000a0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000b0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000c0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000d0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000e0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000f0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000100: 0101 0101 0101 0101 0101 0101 275d 2c73  ............'],s
00000110: 2528 3432 2c39 3939 292c 712c 732c 7129  %(42,999),q,s,q)
00000120: 3b71 3d69 6e63 2721 273b 3f5b 683a 745d  ;q=inc'!';?[h:t]
00000130: 2363 3d68 2b69 6628 616e 7928 283d 3d29  #c=h+if(any((==)
00000140: 6829 5b27 ff09 0c26 5b27 5d29 2702 2727  h)['...&['])'.''
00000150: 0127 3d5b 633a 6966 2863 3e68 2969 643f  .'=[c:if(c>h)id?
00000160: 745d 3b3f 653d 653b 733d 226d 6f64 756c  t];?e=e;s="modul
00000170: 6520 713b 696d 706f 7274 2053 7464 456e  e q;import StdEn
00000180: 763b 5374 6172 743d 2873 2528 302c 3431  v;Start=(s%(0,41
00000190: 292c 3f5b 2727 5d2c 7325 2834 322c 3939  ),?[''],s%(42,99
000001a0: 3929 2c71 2c73 2c71 293b 713d 696e 6327  9),q,s,q);q=inc'
000001b0: 2127 3b3f 5b68 3a74 5d23 633d 682b 6966  !';?[h:t]#c=h+if
000001c0: 2861 6e79 2828 3d3d 2968 295b 27ff 090c  (any((==)h)['...
000001d0: 265b 275d 2927 0227 2701 273d 5b63 3a69  &['])'.''.'=[c:i
000001e0: 6628 633e 6829 6964 3f74 5d3b 3f65 3d65  f(c>h)id?t];?e=e
000001f0: 3b73 3d22                                ;s="

Probieren Sie es online!

Erhöht einen 226-Byte - String durch alle Byte - Werte ohne \0, \n, \r, 'und \.

Der Grund, warum wir diese Zeichen vermeiden, ist:

  • \0 macht den Compiler wütend
  • \nund \rkann nicht in Charlists angezeigt werden
  • ' würde die Charlist beenden
  • \ könnte Probleme verursachen, wenn es vor einem flüchtigen Charakter kommt

Sobald die Zeichenfolge vollständig ist, wird sie mit allen Zeichenfolgen \377umgebrochen \001, wodurch das ursprüngliche Programm erhalten wird.

Οurous
quelle
Die Ausgabe (zumindest bei TIO) ist das Zeichen mit dem Ordnungswert 128, setzt sich jedoch aus den beiden Bytes zusammen C2 80. Entspricht dies dem Verhalten auf Ihrem lokalen Computer?
Jo King
1
@JoKing Oh nein, ich bekomme ein einzelnes Byte auf meinem Computer. TIO mangelt die Ausgabe, wenn UTF-8 nicht gültig ist (und auch die Eingabedateien).
Οurous
1
@JoKing Ich habe die Antwort auf ein neues Format geändert, mit dem das korrekte Verhalten auf TIO angezeigt werden kann.
Οurous
0

Gol> <> , 70 Bytes, 39039000 Iterationen

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||lPaa*5*=?1:1=Q$~$~|:1)lPaa*5*(Q?:|r2ssH##

Wow, das ist viel niedriger als ich dachte ... Nächster Schritt! Machen Sie es mehr Iterationen !!!

Probieren Sie es online!

KrystosTheOverlord
quelle
Es scheint nichts zu löschen, sobald es 500 erreicht hat. Hängt
Jo King,
Funktioniert das überhaupt? Ich kann das "Inkrementieren des letzten Zeichens" nicht zum Laufen bringen
ASCII
@ Nur ASCII Jetzt funktioniert das, sorry vorhin, ich hatte einen Abschnitt durcheinander gebracht, als ich daran gearbeitet habe, das Ganze zu reparieren. Es funktioniert jetzt, sorry für die Unannehmlichkeiten !!!
KrystosTheOverlord
@JoKing Das NUL-Byte ist der Löschvorgang. Jetzt sollte das Programm löschen, bis es fast verschwunden ist. Dann die NUL löschen und das letzte Zeichen inkrementieren. Wenn es ein ~ ist, wird es in ein '#' umgewandelt und kehrt zurück zu normal !!!
KrystosTheOverlord