Code-Golf beinhaltet immer einige Antworten, die die Regeln mehr oder weniger biegen, indem sie Einschränkungen aufheben, die die Herausforderer für selbstverständlich hielten oder einfach nicht bedachten und in den Regeln nicht auflisteten. Eine dieser interessanten Lücken ist die Möglichkeit, mehr auszugeben , als die Herausforderung verlangt, um ein besseres Ergebnis zu erzielen.
Aus diesem Grund können wir einen universellen Code-Golf-Solver schreiben, der die gewünschte Ausgabe ausgibt - wenn Sie sich nicht darum kümmern, dass es Ewigkeiten dauern könnte und viele andere Dinge davor und danach ausgibt.
Alles, was wir ausgeben müssen, ist eine Sequenz, die garantiert jede mögliche Teilsequenz enthält. Für diesen Codegolf ist dies die Ehrenfeucht-Mycielski-Sequenz :
Die Sequenz beginnt mit den drei Bits 010; Jede aufeinanderfolgende Ziffer wird gebildet, indem das längste Suffix der Sequenz gefunden wird, das auch früher in der Sequenz erscheint, und das Bit ergänzt wird, das auf das jüngste frühere Auftreten dieses Suffix folgt.
Jede endliche Teilfolge von Bits tritt zusammenhängend und unendlich oft innerhalb der Folge auf
Die ersten Ziffern der Sequenz sind:
010011010111000100001111 ... (Sequenz A038219 in OEIS ).
Wenn wir 8 Bits der Sequenz zu einem Byte kombinieren, erhalten wir eine ASCII-Ausgabe, die wir auf dem Bildschirm oder in einer Datei ausgeben können und die jede mögliche endliche Ausgabe enthält . Das Programm gibt Teile von pi aus, den Text von „Never gonna give you up“ , ein paar nette ASCII-Grafiken, seinen eigenen Quellcode und alles andere, was Sie ausgeben möchten.
Um die Korrektheit zu testen, sind hier Hashes für die ersten 256 Bytes der Sequenz:
MD5: 5dc589a06e5ca0cd9280a364a456d7a4
SHA-1: 657722ceef206ad22881ceba370d32c0960e267f
Die ersten 8 Bytes der Sequenz in hexadezimaler Schreibweise lauten:
4D 71 0F 65 27 46 0B 7C
Regeln:
Ihr Programm muss die Ehrenfeucht-Mycielski-Sequenz ausgeben (sonst nichts) und 8 Bits zu einem Byte / ASCII-Zeichen kombinieren.
Das kürzeste Programm (Anzahl der Zeichen) gewinnt. Subtrahieren Sie 512 von Ihrer Zeichenanzahl, wenn Sie es schaffen, die Sequenz in linearer Zeit pro generiertem Byte zu generieren .
Antworten:
C –110 Zeichen
Diese Programmversion verwendet den linearen Laufzeitalgorithmus, um die Sequenz zu generieren. Das Subtrahieren von 512 von den 402 Zeichen im Programm ergibt insgesamt negative 110.
Gemäß dem Problem wird das Programm in einer Endlosschleife ausgeführt, die viel Speicherzuweisung erfordert, und die Verwendung
realloc()
, um die Sequenz zusammenhängend zu halten, kann zur Heap-Fragmentierung beitragen. Sie können die Speichernutzung des Programms verbessern, indem Siecalloc(7,8)
in der ersten Zeile durch ersetzencalloc(1,sizeof*v)
. Dies ist besonders auf 32-Bit-Computern hilfreich, bei denen 56 wahrscheinlich um den Faktor zwei zu groß ist.Der Code ist irgendwie unlesbar und nicht auf interessante Weise; dafür entschuldige ich mich. Ehrlich gesagt, auch die ungolfed Version ist nicht besonders klar:
(Der obige ungolfed Code basiert auf dem Code von Grzegorz Herman und Michael Soltys, auf den in der Problembeschreibung und auf der Homepage von Soltys verwiesen wird .)
Vielen Dank an @schnaader und @res für den Hinweis auf einen Fehler in der ursprünglichen Version.
quelle
malloc
Modified-Versionen stoppen die Ausgabe nach etwa 10000 Bytes und weisen weiterhin Speicher zu. Diesprog > out.dat
führt zu einem sofortigen Absturz mit nur ca. 700 KB Speicherverbrauch. Wenn ich einfügenprintf("\n%i\n", size);
nachrealloc
, ist die größte Ausgabe4
. System: Windows 7 Prof. 64-Bit, 4 GB RAM, GCC 4.6.1Ruby,
10910410194 ZeichenImplementierung in Ruby mit regulären Ausdrücken für die Suffixsuche. Da es ziemlich lange dauert, bis der Speicher voll ist, muss das Programm vom Benutzer beendet werden.
Edit: Mir ist gerade aufgefallen, dass es ausreicht, mit der Sequenz zu beginnen
0
.Edit 2: Der Vorschlag von res speichert 2 Zeichen, einige andere, weil wir vorher kein einziges Byte ausschneiden müssen
pack
.quelle
s=(s[/(.*).*\1/][/.#{$1}/]<?1??1:?0)+s
werden zwei weitere Zeichen gespeichert.?C
?Perl, 95 Zeichen
Anfangs hatte ich tatsächlich eine halbwegs anständige Version davon. Dann, als ich Golf spielte, wurde jede Version langsamer. Immer langsamer.
Die ersten drei Zeichen (
$|=
) sind streng genommen nicht erforderlich. Ohne diese Zeichen müssen Sie normalerweise warten, bis das Skript die vollständigen 4096 Byte generiert hat, bevor Sie eine Ausgabe sehen. Und das würde Stunden dauern. Vielleicht Jahrhunderte; Ich bin mir nicht sicher. Habe ich erwähnt, dass sich die Leistung dieses Programms im Laufe der Zeit verschlechtert? Aus diesem Grund fühlte ich mich gezwungen, sie in die Zählung einzubeziehen.Auf der anderen Seite hat dieses Skript eine der hässlichsten Regexen, die ich je erstellt habe, also denke ich, dass ich stolz darauf bin.
quelle