Dies wurde inspiriert von Print a Negative Ihres Codes und Golf a mutual quine .
Betrachten Sie ein Rechteck von Zeichen, die die folgenden Einschränkungen erfüllen:
- Besteht ausschließlich aus druckbaren ASCII-Zeichen
- Abmessungen beide größer als 1
- Jede Zeile und jede Spalte enthält mindestens ein Leerzeichen.
- Jede Zeile und jede Spalte enthält mindestens ein Nicht-Leerzeichen.
Das folgende Beispiel ist ein gültiges 6 x 4-Rechteck:
%n 2e
1 g 3
&* __
3
Ein Negativ für dieses Rechteck ist ein Rechteck mit gleichen Abmessungen, bei dem alle Leerzeichen durch Nicht-Leerzeichen und alle Nicht-Leerzeichen durch Leerzeichen ersetzt werden. Ein Negativ des obigen Rechtecks könnte sein:
f ^
33 >
9 $
^ }|Q'
Jedes nicht durch Leerzeichen druckbare ASCII-Zeichen kann verwendet werden, um ein Leerzeichen zu ersetzen.
Aufgabe
Ihre Aufgabe ist es, ein Programm mit rechteckigem Quellcode zu schreiben, das ein gültiges Negativ an sich selbst ausgibt. Das ausgegebene Negativ muss ebenfalls ein gültiges Programm in derselben Sprache wie das Original sein und die Quelle des Originals ausgeben.
Es darf kein abschließendes Leerzeichen hinzugefügt oder entfernt werden, mit Ausnahme einer einzelnen abschließenden Zeile am Ende einer Ausgabe, die optional ist.
Keines der Programme darf den Quellcode eines der beiden Programme lesen. Es kann auch nicht von REPL-Umgebungen ausgegangen werden.
Wertung
Ihre Punktzahl ergibt sich aus den Dimensionen Ihres Codes (dh wenn sich Ihr Quellcode in einem Rechteck von 12 x 25 befindet, beträgt Ihre Punktzahl 12 * 15 = 180). Zusätzlich erhöht sich Ihre Punktzahl für jedes Zeichen, das in einem Kommentar verwendet wird, um 2 (Wenn Sie /* .. */
einmal in Ihrem Code verwenden und sich Ihr Code in einem 10 x 10-Rechteck befindet, beträgt Ihre Punktzahl 10 * 10 + 8 * 2 = 116).
Die niedrigste Punktzahl gewinnt.
Bei Stimmengleichheit gewinnt die Einsendung mit der geringsten Anzahl von Leerzeichen im Programm (entweder das Original oder das Negativ, je nachdem, welches weniger Leerzeichen hat).
Bleibt noch ein Gleichstand bestehen, gewinnt die frühere Antwort.
Es gibt einen Bonus von -52% , wenn das Original und das Negativ zusammen ein normales Quine ergeben. Beispielsweise:
Original Negative Combined
A A B B BABA
A A B B ABAB
quelle
Antworten:
CJam, (
51 49 47 46 4542 × 2) × 48% = 40,32Wenn Sie den obigen Code ausführen, erhalten Sie folgende Ausgabe:
Läuft was, druckt die Originalquelle zurück.
Die Quelle und die Ausgabe sind einfach vertauschte Zeilen.
Jetzt kommt die Magie.
Das Überlappen der Quelle und der Ausgabe führt zu folgendem Code:
das ist eine perfekte quine!
Probieren Sie sie hier online aus
Wie es funktioniert
Die gesamte Drucklogik befindet sich in der ersten Zeile, in der alle drei später erläuterten Fälle behandelt werden.
Das Array in der letzten Zeile oben ist das Array, dessen Codeblöcke allen drei Fällen entsprechen.
Fall 1
In diesem Fall war die Länge des verbleibenden Stapels 0, als der Block ausgeführt wurde, er hatte nur die Kopie des Blocks selbst, die ursprünglich im dritten Schritt oben herausgesprungen war. Also nehmen wir den Index
0
aus dem letzten Array und führen ihn aus:In diesem Fall ist die zweite Zeile für das Drucken der Ausgabe ein No-Op.
Fall 2
In diesem Fall enthielt der Stapel bereits eine leere Zeichenfolge. Als der kopierte Codeblock ausgeführt wurde, hatte er zwei Elemente - eine leere Zeichenfolge und den Codeblock selbst. Also nehmen wir den Index
1
aus dem letzten Array und führen ihn aus:Fall 3
In diesem Fall hat der Stapel 6 Elemente. Nach dem Aufrufen des letzten Codeblocks beträgt die verbleibende Arraylänge 5. Wir nehmen den Index
5
aus dem Array und führen ihn aus. (Beachten Sie, dass in einem Array von3
Elementen index index5
ist.5%3 = 2
)quelle
Python, 97 x 2 + 2 = 196
Für den Anfang keine gute Lösung, aber zumindest funktioniert es (glaube ich).
Ausgabe:
quelle
C Jam, (
5856544846 × 2) × 48% = 44,16welche druckt
Die Nicht-Leerzeichen in jeder Zeile bleiben zwischen den beiden Quines gleich.
Aber jetzt der wirklich süße Teil:
ist eine Quine! :)
Teste es hier.
Wie es funktioniert
Ich empfehle Ihnen, zuerst die Erklärung zu meinem anderen Beitrag zu lesen, da hier die Grundlagen des Quining in CJam im Allgemeinen erläutert werden.
Dieser ist etwas kniffliger. Für das gegenseitige Quine ändere ich wie im anderen Fall die Zeichenfolgendarstellung des Blocks, indem ich vor oder nach jeder Zeile Leerzeichen hinzufüge und eine 0 durch eine 2 tausche, sodass das resultierende Programm die Leerzeichen an das entgegengesetzte Ende setzt.
Beachten Sie, dass sich die Leerzeichen überhaupt nicht auf die Quines auswirken. In der ersten befinden sie sich in einem Block, der nicht wirklich verwendet wird, und in der zweiten befinden sie sich um den gesamten Code.
Um eine regelmäßige Quine zu erhalten, wenn beide kombiniert werden, müssen wir einen Weg finden, um all diese Modifikationen zu vermeiden. Beachten Sie, dass die Struktur von Whitespace und Code bedeutet, dass durch die Kombination von beiden die Gesamtheit eines Quines in das andere eingefügt wird. Wenn wir also den gesamten Änderungscode in einen Block einfügen, können wir diesen Block abhängig von seinem tatsächlichen Inhalt ausführen.
Jetzt habe ich also diesen Block ... für die gegenseitigen Quines enthält er nur den Code, den ich eigentlich ausführen möchte. Für das kombinierte Quine enthält es auch wieder das gesamte Quine in einer zufälligen Position, was keinen Sinn ergibt ... aber da es ein Block ist, wird es nicht automatisch ausgeführt. So können wir anhand des Inhalts dieses Blocks bestimmen, ob der String geändert werden soll. Dafür
_`'"#)!
ist es da. Es dupliziert den Block, konvertiert ihn in einen String, sucht nach dem Zeichen"
(das in den Quines nur außerhalb des Blocks vorkommt) - die Suche gibt zurück,-1
wenn das Zeichen nicht gefunden wird, und ansonsten eine positive ganze Zahl - und erhöht das Ergebnis und negiert es logisch. Wenn also a"
gefunden wurde, ergibt dies,0
andernfalls ergibt es1
. Jetzt machen wir es einfach*
, der den Block einmal ausführt, wenn das Ergebnis 1 war und ansonsten gar nicht.Schließlich funktioniert der Änderungscode wie folgt:
Inanspruchnahme der Prämie (12 x 10) * 48% = 57,6
Es hat sich herausgestellt, dass dieser Code mit einigen Änderungen sehr einfach auf mehrere Zeilen aufgeteilt werden kann. Wir addieren 2 Zeichen, um 48 in einer Reihe zu erhalten, die wir dann bequem durch 8 teilen können, so dass wir 8 Zeilen mit 6 Codezeichen und 6 Leerzeichen haben. Dazu müssen wir auch einige Zahlen ändern und einen oder zwei Operatoren neu anordnen, damit sie nicht auf beide Zeilen aufgeteilt werden. Das gibt uns eine funktionierende Version mit der Größe 12 x 8 ... einmalig. Also fügen wir einfach zwei Zeilen hinzu, die nichts bewirken (eine 1 drücken, eine 1 drücken, eine 1 drücken, eine 1 drücken ...), und erhalten 12 x 10 :
Wie der vorherige erzeugt dies
(Randnotiz: In den Zwischenzeilen muss nicht immer links und rechts gewechselt werden, sondern es ist nur die Position der ersten und letzten Zeile wichtig. Links und rechts können für alle anderen Zeilen beliebig gewählt werden.)
Und durch reinen Zufall funktioniert das ganze Quine auch noch:
(Ich sage Zufall, weil der Teil, der dafür sorgt, dass der innere Code nicht ausgeführt wird, jetzt seltsamerweise mit dem anderen Quine verwechselt wird, aber es funktioniert trotzdem gut.)
Davon abgesehen hätte ich
1;
meiner ursprünglichen Einreichung nur 44 Zeilen hinzufügen können , um die Kopfgeldanforderung zu erfüllen,12 x 10
sieht aber viel ordentlicher aus. ;)Edit: Haha, als ich "purer Zufall" sagte, hätte ich nicht besser sein können. Ich habe mir angesehen, wie das letzte Quine jetzt tatsächlich funktioniert, und es ist absolut lächerlich. Es gibt drei verschachtelte Blöcke (4 tatsächlich, aber der innerste ist irrelevant). Der einzig wichtige Teil des innersten dieser 3 Blöcke ist, dass er einen enthält
"
(und nicht den, den er in der ursprünglichen Einreichung getan hat, sondern den'"
, der am Ende verwendet wird, um nach demselben Zeichen zu suchen). Die Grundstruktur des Quines ist also:Lassen Sie uns das analysieren:
Das mag zwar etwas komisch, aber da der innere Block eine einzelne Zeichenfolge auf dem Stapel belässt
)!*
, verwandelt sich diese zufällig in eine leere Zeichenfolge. Die einzige Bedingung ist, dass das Zeug im inneren Block danach+
nichts mehr mit dem Stapel zu tun hat, also schauen wir uns das an:quelle
Y/2
in der kombinierten Quine sein?CJam,
42,37,33 × 2 = 66welche druckt
(Die Zeilen werden vertauscht und a
1
wird zu a0
.)Teste es hier.
Wie es funktioniert
Zunächst sollten Sie das grundlegende CJam-Quine verstehen:
Die geschweiften Klammern definieren einfach einen Codeblock, wie eine Funktion, die nicht sofort ausgeführt wird. Wenn ein nicht ausgeführter Block auf dem Stapel verbleibt, wird sein Quellcode (einschließlich geschweifter Klammern) gedruckt.
_
dupliziert den Block und~
führt die zweite Kopie aus. Der Block selbst drückt einfach die Zeichenfolge, die enthält_~
. Dieser Code belässt den Stack also im folgenden Zustand:Der Block und der String werden am Ende des Programms einfach hintereinander gedruckt, was dies zu einem Quine macht.
Das Schöne daran ist, dass wir im Block tun können, was immer wir wollen, und es bleibt ein Quine, da jeder Code automatisch im Blockinhalt gedruckt wird. Wir können den Block auch modifizieren, indem wir seine Zeichenfolgendarstellung mit
`
(die nur eine Zeichenfolge des Blocks mit geschweiften Klammern ist) erhalten.Schauen wir uns nun diese Lösung an. Beachten Sie, dass jeder Teil des gemeinsamen Quines den quine-ähnlichen Block mit
_~
und enthältL
. DasL
schiebt einen leeren String auf den Stack, was nicht zur Ausgabe beiträgt. Also hier ist, was der Block tut:Dies erledigt also den Quine-Teil, tauscht jedoch eine 1 gegen eine 0 und stellt eine weitere Zeile mit einem voran
L
, wobei der obige Code ein Leerzeichen enthält. Der Haken ist, dass die Reihenfolge dieser beiden Zeilen durch das Vertauschen im Inneren bestimmt wird{ }*
. Und weil der äußere Teil des gemeinsamen Quines das0
davor befindliche durch ein ersetzt1
, führt es diesen Tausch niemals aus und stellt daher die ursprüngliche Reihenfolge wieder her.quelle
C Jam, 27 × 2 = 54
Ausgabe:
'A'B>
vergleicht die Zeichen A und B.' '\n >
gibt 1 zurück, weil 32> 10 und' \n' >
gibt 0 zurück, weil die beiden Leerzeichen gleich sind.quelle
CJam,
3029 × 2 = 58Ausgänge:
welches die ursprüngliche Quelle ausgibt.
Dies basiert auf dem gleichen Prinzip wie meine andere Lösung.
Probieren Sie es hier online aus
quelle