Schreiben Sie ein Programm, das die folgende 80-stellige Zeile ausgibt:
Dieses Programm von codegolf.stackexchange.com erlaubt es sich, einen String zu kodieren.
Akzeptiert dann eine Eingabezeile und druckt den Quellcode mit möglicherweise neu angeordneten Codepunkten (keiner hinzugefügt und keiner gelöscht). Wenn dieser Code ausgeführt wird, muss dasselbe geschehen, mit der Ausnahme, dass die gedruckte Zeile die letzte Eingabezeile ist.
Der reguläre Ausdruck ^[A-Za-z0-9. ]{80}$
im Perl-Stil passt zu jeder Eingabezeile. Sie können keine zusätzlichen Annahmen treffen.
Die Bewertung einer Einreichung ergibt sich aus der Anzahl der Codepunkte im Quellcode abzüglich 94 . Weniger ist besser.
Der Code darf nichts tun, was in einem Quine nicht akzeptabel wäre ( z . B. Lesen von Dateien). Insbesondere muss jede Einsendung mit einer negativen Punktzahl irgendwie schummeln, wie 93! ist kleiner als 64 80 .
Hinzugefügt am 21.04.2014: Der gesamte Quellcode Ihres Programms muss in der Zeichencodierung, unter der Sie Codepunkte zählen, wohlgeformt sein. Beispielsweise können Sie nicht 80 aufeinanderfolgende Bytes im UTF-8-Trailing-Byte-Bereich (80..BF) verwenden und jedes als einzelnes U + FFFD-ERSATZZEICHEN (oder schlimmer noch als gar kein Codepunkt) zählen.
Wenn die Codierung mehrere Möglichkeiten zum Codieren eines Codepunkts ( z. B. SCSU ) zulässt , darf Ihr Programm sowie alle von ihm direkt oder indirekt generierten Programme nur eines von ihnen verwenden (oder zumindest alle müssen im gesamten Code gleich behandelt werden) ).
Antworten:
GolfScript,
231162131Wie es funktioniert
Wir beginnen mit der Auswahl von 94 verschiedenen Zeichen, die für die Codierung eines Strings permutiert werden. Alle 94 Zeichen würden funktionieren, aber wir wählen die folgenden aus Golfgründen:
Nennen wir das Array dieser Zeichen "&".
Die Eingabezeile enthält immer 81 Zeichen (einschließlich des LF). Alle diese Zeichen sind in den ersten 65 Zeichen von "&" enthalten. Dies ist der einzige Grund für die Auswahl von Zeichen in den oberen 128 Bytes.
Wir ersetzen jedes Zeichen des Strings durch seinen Index in "&", so dass LF zu 0 wird, Leerzeichen zu 1 usw.
Wir betrachten die 81 erhaltenen Zahlen als die Ziffern einer einzelnen Zahl zur Basis 65. Nennen wir diese Nummer "N".
Nun werden alle möglichen Permutationen von "&" aufgezählt und die der Zahl entsprechende Permutation von oben abgerufen. Dies wird auf folgende Weise erreicht:
c = 1
und einA = []
.N % c
toA
.N = N / c
und einc = c + 1
.c < 95
, gehe zurück zu 2.i = 0
und eins = ""
.&[A[i]]
Sie das Zeichen ab , hängen Sie es an "s" an und entfernen Sie es von "&".i = i + 1
.i < 94
zurück zu 6.Angenommen, wir haben Codeblöcke "E" und "D", die eine Zeichenfolge wie oben erläutert codieren und decodieren.
Jetzt brauchen wir einen Wrapper für die Codeblöcke, die den Anforderungen der Frage entsprechen:
Dies bewirkt Folgendes:
{…}.~
Definiert einen Block, dupliziert ihn und führt die zweite Kopie aus. Die erste Kopie bleibt auf dem Stapel.\.$
Vertauscht die codierte Zeichenfolge mit dem Block und erstellt eine Kopie der codierten Zeichenfolge mit sortierten Zeichen.[{}/]:&;
wandelt den String von oben in ein Array um, speichert ihn in "&" und verwirft ihn.D puts
decodiert den codierten String und gibt das Ergebnis aus.'"#{`head -1`}"'~
Liest eine Eingabezeile durch Ausführenhead -1
in der Shell.E "'".@+\+
codiert die Zeichenfolge und fügt ein einfaches Anführungszeichen hinzu.\'.~'
tauscht die codierte Zeichenfolge und den Block aus und hängt die Zeichenfolge an'.~'
.Nachdem der Block ausgeführt wurde, druckt GolfScript den Inhalt des Stapels (codierte Zeichenfolge, Block
'.~'
) und beendet ihn."E" kann wie folgt definiert werden:
"D" kann wie folgt definiert werden:
Abschließendes Golfen:
Ersetzen Sie
\.$[{}/]:&;0&@
durch0@.$[{}/]:&\
, um zwei Zeichen zu speichern.Definieren Sie die Funktion
{;65base}:b
zum Speichern eines Zeichens.Entfernen Sie alle Leerzeichen mit Ausnahme des nachfolgenden LF und des LF in der Zeichenfolge.
Beispiel
quelle
Perl
1428,1099Dieser enthält 1193 ASCII-Zeichen (einschließlich 960 permutierter Binärziffern). 1193 - 94 = 1099
Mein erster Entwurf
Bevor ich Dennis einen Vorschlag machte, auf Binär umzuschalten, permutierte mein Programm Oktalziffern.
Mein erstes Design codiert jede Zeichenfolge in 160 Oktalzeichen mit 2 Zeichen pro Zeichen. Diese Kodierung hat 100 8 = 64 verschiedene Zeichen. Das Oktalsystem besteht aus 8 verschiedenen Ziffern. Das Programm muss 160 Kopien jeder Ziffer enthalten, damit 8 × 160 = 1280 Ziffern möglich sind.
Ich behalte 160 Stellen in
$s
und die anderen 1120 Stellen in$t
. Ich beginne mit einem Programm, das kein Quine ist, sondern nur die Zuweisungen für$s
und$t
für den nächsten Lauf ausgibt . Das ist es:(() = $s =~ /$_/g))
ist eine Zuweisung zu einer leeren Liste von Variablen. Ich nehme diesen Trick aus dem Kontext-Tutorial bei PerlMonks . Erzwingt den Listenkontext für den Match-Operator=~
. Im skalaren Kontext wäre die Übereinstimmung wahr oder falsch, und ich bräuchte eine Schleife,$i++ while ($s =~ /$_/g)
um die Übereinstimmungen zu zählen. Im Listenkontext$s =~ /$_/g
ist eine Liste von Übereinstimmungen. Ich habe diese Liste in den skalaren Kontext einer Subtraktion gestellt, sodass Perl die Listenelemente zählt.Um eine Quine zu machen, nehme ich die Form
$_=q{print"\$_=q{$_};eval"};eval
der Perl-Quines bei Rosetta Code . Dieser ordnet einen Stringq{...}
zu$_
und ruft dann aufeval
, sodass ich meinen Code in einem String haben und ihn auch ausführen kann. Mein Programm wird zu einem Quine, wenn ich meine drittletzten Zeilen in$_=q{
und einbinde};eval
und meine letztenprint
in ändernprint "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"
.Schließlich spiele ich mein Programm ab, indem ich die erste Zuweisung
$t
in einen Kommentar ändere und zusätzliche Zeichen entferne.Dies hat 1522 ASCII-Zeichen (einschließlich 1280 permutierten Oktalzeichen).
1522 - 94 = 1428
Der Umstieg auf Binär
In den Kommentaren bemerkte Dennis, dass 960 permutierte Binärziffern weniger als 1280 Oktalziffern sind. Also habe ich die Anzahl der permutierten Stellen für jede Basis von 2 bis 16 grafisch dargestellt.
Obwohl die Basis 8 ein lokales Minimum darstellt, ergeben die Basen 2 und 3 und 4 mit 960 permutierten Stellen die beste Basis. Für Code-Golf ist Basis 2 am besten geeignet, da Perl Konvertierungen für Basis 2 hat.
Durch Ersetzen von 1280 Oktalzeichen durch 960 Binärzeichen werden 320 Zeichen gespeichert.
Das Umschalten des Codes von Oktal auf Binär kostet 8 Zeichen:
oct
deroct'0b'.$_
Kosten 7./../g
der/.{6}/g
Kosten 2."%02o"
zu "% 06b" `kostet 0.160
zu480
Kosten 0.0..7
Zum0,1
Speichern wechseln 1.Ich habe einige Perl-Golftipps gelernt . Sie speichern 14 Zeichen:
'A'..'Z','a'..'z','0'..'9'
anA..Z,a..z,0..9
, mit Barewords und nackten Zahlen, spart 12 Zeichen."\n"
um$/
2 Zeichen zu speichern.Ich spare 3 Zeichen, indem ich den
#$t
Kommentar an das Ende der Datei verschiebe. Das entfernt die neue Zeile, die den Kommentar beendet, und ein Literal\n
in dem Quine.Diese Änderungen speichern insgesamt 329 Zeichen und reduzieren meine Punktzahl von 1428 auf 1099.
quelle