Die längste iterierende Quine


10

Wie wir wissen, ist ein Quine ein Programm, das seinen eigenen Quellcode ausgibt. Es ist jedoch auch möglich, ein Programm zu schreiben, das ein anderes, anderes Programm ausgibt, das das erste Programm erneut ausgibt. Zum Beispiel das Python 2-Programm

x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3

gibt beim Ausführen den folgenden Text aus:

print """x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3"""

Wenn es als Python-Programm ausgeführt wird, wird der ursprüngliche Code erneut ausgegeben. Dies wird als iterierende Quine bezeichnet . Da Sie es zweimal ausführen müssen, um den ursprünglichen Code zurückzugewinnen, haben wir die Periode 2 . Aber natürlich sind viel höhere Perioden möglich.

Ihre Herausforderung besteht darin, eine iterierende Quine mit einem möglichst langen Zeitraum in maximal 100 Byte in der Sprache Ihrer Wahl zu schreiben . (Beachten Sie, dass mein Beispiel oben nicht zu dieser Spezifikation passt, da es 119 Byte enthält, einschließlich der nachfolgenden Zeilenumbruch.)

Bitte beachten Sie die folgenden Regeln und Erläuterungen:

  • Es gelten die üblichen Quine-Regeln, dh Ihr Programm kann keine Sprachfunktionen verwenden, mit denen es direkt auf seinen eigenen Quellcode zugreifen kann.
  • Die iterierten Ausgaben müssen schließlich zu genau Ihrem ursprünglichen Code zurückkehren, und Sie müssen eine Demonstration oder einen Beweis dafür beifügen.
  • Sie müssen auch eine Erklärung hinzufügen, warum der Zyklus so lang ist, wie Sie es sagen. Dies muss nicht unbedingt ein mathematischer Beweis sein, sondern sollte jemanden überzeugen, der mit Ihrer Sprache vertraut ist. (Diese Regel ist hier, weil ich erwarte, dass einige der Antworten sehr, sehr große Zahlen enthalten.)
  • Es ist in Ordnung, etwas wie "mindestens 1.000.000 Iterationen" zu sagen, anstatt die genaue Anzahl anzugeben, solange Sie nachweisen können, dass es mindestens so lang ist. In diesem Fall wäre Ihre Punktzahl 1.000.000. Andernfalls ist Ihre Punktzahl die Periode Ihrer Quine.
  • Das 100-Byte-Limit gilt nur für Ihr ursprüngliches Programm - die von ihm ausgegebenen Programme können länger sein, obwohl sie natürlich irgendwann wieder auf 100 Byte reduziert werden müssen, um Ihren ursprünglichen Code auszugeben.
  • Sie können davon ausgehen, dass Ihr Computer über unendlich viel RAM und unendlich viel Laufzeit verfügt. Sie können jedoch keine Datentypen mit unbegrenzter Genauigkeit (z. B. Ganzzahlen) annehmen, wenn Ihre Sprache diese nicht hat. Sie können davon ausgehen, dass die Länge der Eingabe, die Ihr Parser verarbeiten kann, unbegrenzt ist.
  • Die höchste Punktzahl gewinnt.

Bitte beachten Sie: Es gibt eine Herausforderung namens Quit Whining. Starten Sie Quining , bei dem auch Quines iteriert werden. Abgesehen davon, dass sie auf demselben Konzept basieren, handelt es sich jedoch um völlig unterschiedliche Arten von Herausforderungen. Der andere ist Straight-Up-Code-Golf, während dieser (absichtlich!) Wirklich ein geschäftiges Biberproblem in der Verkleidung ist. Die Techniken, die erforderlich sind, um eine gute Antwort auf diese Frage zu erhalten, unterscheiden sich wahrscheinlich stark von denen, die zur Beantwortung der anderen Frage erforderlich sind, und dies ist sehr beabsichtigt.


1
@LeakyNun Ich weiß nicht, ob Sie oder ein Mod Ihre Antwort gelöscht haben, aber wenn ich erkläre, was daran falsch war, werden Sie vielleicht verstehen, warum dies kein Duplikat ist. Diese Frage gibt ein 100-Byte-Limit für die Quelllänge an, sodass Sie mit dieser Methode nicht "so hoch wie Sie wollen" gehen können. Das ist der springende Punkt dieser Frage. Um dies zu beantworten, müssten Sie die längste Version veröffentlichen, die in 100 Zeichen passt, und den Zeitraum angeben. Was Sie gepostet haben, wäre ein guter erster Versuch, aber es ist sehr unwahrscheinlich, dass Sie der Gewinner sind.
Nathaniel

1
@ Dave Die Herausforderung besteht genau darin, eine große Anzahl in einer kleinen Anzahl von Bytes anzugeben, ja. Das ist das ganze Prinzip, nach dem es entworfen wurde. Die Frage ist, ist 3 ^^^ 3 die höchste Zahl, die Sie in Ihrer Sprache in 100 Bytes angeben können, oder gibt es eine größere? Darum geht es bei dieser Herausforderung. Es ist der Kern davon. Ich wollte, dass die Leute das tun. Es ist super, super frustrierend, es aufgrund einer oberflächlichen Ähnlichkeit mit einer Herausforderung, die nichts von dieser Struktur hat, geschlossen zu haben.
Nathaniel

1
@ Dave (zweiter Kommentar), aber wenn Sie klug sind, müssen Sie überhaupt nicht durch Maschinenpräzision eingeschränkt sein. Ich würde erwarten, dass wettbewerbsfähige Antworten einen Zeitraum haben, der viel länger als 2 ^ (2 ^ 64) ist.
Nathaniel


1
@PeterTaylor, das ist ein viel näheres Thema, aber es ist immer noch eine ganz andere Herausforderung - das Drucken einer Zahl unterscheidet sich erheblich von einer großen Anzahl von Malen. Ich würde es natürlich vorziehen, überhaupt nicht geschlossen zu sein.
Nathaniel

Antworten:


10

PHP, Zeitraum 2.100.000.000

Wer hätte gedacht, dass dies in PHP möglich ist?! :-)

Dies ist tatsächlich meine erste Quine und sie ist 99 Bytes lang:

<?$i=1;$i*=21e8>$i;printf($a='<?$i=%d;$i*=21e8>$i;printf($a=%c%s%c,++$i,39,$a,39);',++$i,39,$a,39);

Obwohl PHP größere Zahlen unterstützt als 2 * 10^8durch Umschalten von integerauf double, funktioniert das Inkrement nicht mehr (führt zu einer Endlosschleife) und ich habe keine andere Lösung gefunden, die in die 100 Bytes passt. Noch.

Der Beweis ist ziemlich einfach, da er nur bei jeder Iteration hochzählt, bis der Rücksetzpunkt bei 2,1 Milliarden erreicht ist.

Dank an Dave , der den Ansatz in Pseudo-Code in den Kommentaren gepostet hat , und an Bob Twells , von dem ich den Code für ein minimales PHP-Quine kopiert habe.

Testprogramm (sloooooow):

<?php
$o = file_get_contents('quine.php');
for ($i = 0; $i < 22e8; $i++) {
    if ($i%2==0) exec('php q > p'); else exec('php p > q');
    $a = file_get_contents(($i%2==0) ? 'p' : 'q');
    echo "\r" . str_pad($i,6,' ') . ":\t$a";
    if ($a == $o) {
        die;
    }
}

Zumindest bin ich der erste, der antwortet.


1
Randnotiz: Dies liegt in der Größenordnung von ~ 10 ^ 9.322219295.
LegionMammal978

8

Mathematica, Zeitraum E8.5678 # 3 E2.1923 # 4 ~ E6.2695 # 3 # 2

Print[ToString[#0, InputForm], "[", #1 - 1 /. 0 -> "Nest[#!,9,9^9^99!]", "]"] & [Nest[#!,9,9^9^99!]]

Beachten Sie, dass die Ergebnisse in Hyper-E-Notation beschrieben sind . Die Iterationen ersetzen das Finale Nest[#!,9,9^9^99!]durch die Dezimalerweiterungen von Nest[#!,9,9^9^99!]- 1, Nest[#!,9,9^9^99!]- 2, Nest[#!,9,9^9^99!]- 3, ..., 3, 2, 1 und zurück zu Nest[#!,9,9^9^99!].


würden Fakultäten nicht schneller wachsen?
Maltysen

1
Ich kenne Mathematica nicht, aber ist das nicht ein Verstoß gegen die Regeln für eine Quine - das Lesen des eigenen Quellcodes? ToString[#0, InputForm]
Daniero

also nur 9 !!!! funktioniert nicht? idk weil ich meine mathematica rpi gerade nicht bei mir habe.
Maltysen

@Maltysen Das berechnet die doppelte Fakultät der doppelten Fakultät von neun oder (9 !!) !! ≈ 2.116870635 · 10¹²⁰²
LegionMammal978

@ Daniero Ich meine, die Idee ähnelt einer Standard-CJam {"_~"}_~, also denke ich, dass sie gültig sein sollte ...
LegionMammal978

5

R, zufällige Periode mit Erwartung 2 ^ 19936-0.5

f=function(){
    options(scipen=50)
    body(f)[[4]]<<-sum(runif(623))
    0
    cat("f=")
    print(f)
}

Der Standard-Zufallszahlengenerator von R hat eine Periode von 2 ^ 19937-1 und eine Gleichverteilung in 623 aufeinanderfolgenden Dimensionen. Somit wird irgendwo (aber nur einmal) in seiner Periode ein 623 langer Vektor von Nullen sein. Wenn wir dort ankommen (und mit dem Beginn der Sequenz ausgerichtet sind), ist die Summe der nächsten 623 zufälligen U [0,1] -Zahlen Null und wir kehren zu unserem ursprünglichen Programm zurück.

Beachten Sie, dass das Programm mit sehr hoher Wahrscheinlichkeit mehrmals denselben Zustand ungleich Null durchläuft, bevor es auf Null zurückkehrt. Zum Beispiel ist die Summe 311,5 am wahrscheinlichsten, und es gibt sehr viele Möglichkeiten, die passieren können, aber das RNG erlaubt, dass die Periode für 0 länger ist als die Periode für 311,5.


Nicht sicher, welche Punktzahl Sie diesem Eintrag zuweisen möchten: P
JDL

1
Gemäß den Regeln: "Es ist in Ordnung, etwas wie" mindestens 1.000.000 Iterationen "zu sagen, anstatt die genaue Zahl anzugeben." Meiner Meinung nach ist es also "mindestens 1 Iteration", denn wenn wir beim ersten Versuch wirklich Glück haben ...;)
YetiCGN

Im Gegensatz zu vielen Standardlücken wie „Ich könnte eine zufällige Eingabe generieren, die Antwort ist da“ ist dies ein wirklich guter Beweis dafür, dass die genaue Antwort zwangsläufig eintreten wird, und es wird eine sehr gute Schätzung gegeben. Nett!
Andreï Kostyrka

1
Sobald das Programm einmal in seinen Grundzustand zurückkehrt, hat es eine nicht zufällige Periode von genau 2 ^ 19937-1.
JDL

Die Ausgabe stimmt nicht mit dem tatsächlichen Programm überein (es fehlt ein bisschen Leerzeichen). Außerdem wird der Status zwischen den Programmaufrufen nicht beibehalten, sodass der Zeitraum weder eine genaue noch eine konsistente Zahl ist
Jo King,

1

JavaScript, Zeitraum 9.007.199.254.700.000

Ich werde nicht gewinnen, aber es hat Spaß gemacht, mit JavaScript an dieser Herausforderung zu arbeiten:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)

Folgt dem folgenden Zyklus:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699999-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699998-1||90071992547e5)
// etc...
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),3-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),2-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
// and so on

Hinweis: Sie können es um 18 Byte verkürzen, während Sie nur ~ 0,08% der Punktzahl entfernen, wie folgt:

a="a=%s;console.log(a,uneval(a),%.0f-1||9e15)";console.log(a,uneval(a),1-1||9e15)

1

C, Zeitraum 2.100.000.000

unsigned long long i;main(a){i=1;i*=21e8>i;printf(a="ungisned long long i;main(a){i=%d;i*=21e8>i;printf(a=%c%s%2$c,++i,34,a);}",++i,34,a);}

Basierend auf der PHP-Antwort (offensichtlich). Wird mit Erklärung aktualisiert, wenn ich Zeit habe.


1

C (gcc) , 66 Bytes, Periode 2 ^ 64

f(s){printf(s="f(s){printf(s=%c%s%1$c,34,s,%lu+1L);}",34,s,0+1L);}

Probieren Sie es online aus!

2 ^ 64 Zahlen sind in einer unsigned longganzen Zahl verfügbar . Daher ein Zeitraum von 2 ^ 64.


1

Python 2

9((99↑↑(9((99↑↑(9((99↑↑(9↑↑51))9)1))9)1))9)+1

99(99↑↑12)+1

b=0;s="print'b=%d;s=%r;exec s'%(-~b%eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9))),s)";exec s

Probieren Sie es online aus!

Im Code b=0ändert sich das zu b=1dann b=2und so weiter, bis es erreicht und b=decimal expansion of the perioddann wieder zurückgesetzt wirdb=0


1
9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9ist viel höher als 9**9**99**99**99**99**99**99**99**99**99**99**99**99. Das heißt, Sie könnten so etwas eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9)))für viel viel höhere Zahlen tun .
Bubbler

Was bedeutet Peroid?
SS Anne


1
@ Mukundan Ich denke du meinst vielleicht Periode, aber ich bin mir nicht sicher. Ich verstehe, was Tetration ist.
SS Anne

@SSAnne Entschuldigung, es war ein Tippfehler, danke für den Hinweis
Mukundan

0

Gol> <> , 70 Bytes, Zeit 325883196621297064957600206175719056476804879488288708188003274919860959534770101079512433396348062803055739640225395758790852315876868469390603793729639715908136196505908165227136154287969475839017544811926036808089596209081885772040898530121921794489026069641113281250

Andere weise als wirklich groß bekannt (3.25E270)

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

Dies ist eigentlich eine geänderte Version der Antwort, die ich auf den 500-Byte-Iterator gegeben habe

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||//if last is equal to 1 and length is 71, delete the delete char, if the last char is '~', delete and push 'H#', which will later return to 'H##', completing the cycle!
lPffXfX=?1:1=Q$~$~|          //if length is equal to 15^15^15, then start delete process(append ascii one)
:1)lPffXfX(Q?:|              //if the last character is not 1 (the delete checker), and length is less than 15^15^15, duplicate the last value and append
r2ssH##                      //push the " to the front and output the whole thing

Hoffentlich habe ich die Punktzahl richtig verstanden und es gibt keine Fehler. Es gibt keine wirkliche Möglichkeit, diesen Wert tatsächlich zu berechnen, es ist theoretisch. Aber Mann, das ist eine riesige Zahl !!!

Probieren Sie es online aus!

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.