Ich dachte, das wäre eine lustige Herausforderung für alle und ich bin gespannt auf die Lösungen, die die Leute finden.
Drucken Sie die Texte "12 Days Of Christmas"
On the first day of Christmas,
my true love gave to me,
A partridge in a pear tree.
On the second day of Christmas,
my true love gave to me,
Two turtle doves,
And a partridge in a pear tree.
...
On the twelfth day of Christmas,
My true love gave to me,
Twelve drummers drumming,
Eleven pipers piping,
Ten lords-a-leaping,
Nine ladies dancing,
Eight maids-a-milking,
Seven swans-a-swimming,
Six geese-a-laying,
Five golden rings,
Four calling birds,
Three french hens,
Two turtle doves,
And a partridge in a pear tree.
Regeln
- Sie müssen sich keine Sorgen um die Großschreibung machen. Der gesamte Text kann zwischen Groß- und Kleinschreibung unterscheiden
- Sie können Satzzeichen vernünftigerweise ignorieren: Bindestriche können Leerzeichen sein, Kommas und Punkte können ignoriert werden
- Zwischen jedem Vers sollte eine Leerzeile stehen
- Sie müssen Ihre Zahlen ordinalisieren: " erster Weihnachtstag", " Vier rufende Vögel" usw
Antworten:
Brainfuck - 2.974
Ich bin ziemlich stolz darauf. Das hört sich nach einer ziemlich großen Zahl an, aber denken Sie daran, dass ich keine externen Komprimierungsbibliotheken verwendet habe und dass sich nirgendwo der Originaltext in meinem Programm befindet. Keiner der anderen Beiträge kann das behaupten. Dies ist alles handcodiert. Naivere Textgeneratoren geben mehr als 39 KB für diesen Text aus, daher würde ich sagen, dass dies eine signifikante Verbesserung darstellt.
Leider ist dies etwa 600 Zeichen länger als die eigene Ausgabe, aber was auch immer. Die Zeichen c, h, m, r, w bleiben in einem Array und werden zum Drucken des gesamten Texts verwendet. Zwei Felder rechts von je zwölf Feldern protokollieren, an welchem Tag wir zählen und für welche Elemente wir ausgeben können. Möglicherweise kann ich es ein wenig optimieren, indem ich die Speicherzuordnung neu organisiere, um die Druckzeichen zwischen die beiden Zählfelder zu bringen, um so lange Ketten von
<<<<<<<
und zu vermeiden>>>>>>
, aber das wäre an dieser Stelle eine Menge Arbeit. Ich könnte wahrscheinlich auch einige bessere Startzeichen mit Frequenzanalyse auswählen, um das Inkrementieren / Dekrementieren zu minimieren, aber wie auch immer.Dies hängt davon ab, ob 8-Bit-Umbruchzellen ordnungsgemäß funktionieren.
Ungolfed:
quelle
Perl,
438291 ZeichenInspiriert von Jeff Burdges 'DEFLATE-Komprimierung , Venteros komprimiertem Ruby-Code und JBs Lingua :: EN :: Numbers gelang es mir, meine Eingabe auf 291 Zeichen (naja, Bytes) einschließlich Dekomprimierungscode zu komprimieren. Da das Programm einige nicht druckbare Zeichen enthält, habe ich es im MIME Base64-Format bereitgestellt :
Um das Programm zu entschlüsseln, können Sie das folgende Hilfs-Perl-Skript verwenden:
Speichern Sie die Ausgabe in einer Datei mit dem Namen
12days.pl
und führen Sie sie mit ausperl -M5.01 12days.pl
. Wie bereits erwähnt, muss das Lingua :: EN :: Numbers- Modul installiert sein, damit der Code funktioniert.Falls Sie sich fragen, sieht der lesbare Teil des Codes einfach so aus:
Dabei
...
steht das für 254 Bytes RFC 1950- komprimierten Perl-Code. Unkomprimiert ist der Code 361 Zeichen lang und sieht folgendermaßen aus:Das Schreiben dieses Codes war eine seltsame Art von Golfübung: Es stellte sich heraus, dass die Maximierung der Wiederholung und die Minimierung der Anzahl der verwendeten unterschiedlichen Zeichen viel wichtiger sind als die Minimierung der Anzahl der rohen Zeichen, wenn die relevante Metrik die Größe nach der Komprimierung ist .
Um die letzten Zeichen herauszufiltern, habe ich ein einfaches Programm geschrieben, um kleine Variationen dieses Codes auszuprobieren und das zu finden, das am besten komprimiert. Für die Komprimierung habe ich Ken Silvermans KZIP- Dienstprogramm verwendet, das in der Regel selbst bei maximalen Komprimierungseinstellungen bessere Komprimierungsraten (auf Kosten der Geschwindigkeit) liefert als Standard-Zlib. Da KZIP nur ZIP-Archive erstellt, musste ich natürlich den unformatierten DEFLATE-Stream aus dem Archiv extrahieren und ihn in einen RFC 1950-Header und eine Prüfsumme verpacken. Hier ist der Code, den ich dafür verwendet habe:
Wenn das wie ein schrecklicher Schlitten aussieht, dann ist es genau das, was es ist.
Aus historischen Gründen ist hier meine ursprüngliche 438-Zeichen-Lösung, die eine bessere Ausgabe, einschließlich Zeilenumbrüchen und Interpunktion, generiert:
Höhepunkte dieser Version sind die beiden Regexps
s/e?t? .*/th/,s/vt/ft/
, die aus den Kardinälen am Anfang der Geschenklinien die Ordnungszahlen für 4 bis 12 bilden.Dieser Code kann natürlich auch mit dem oben beschriebenen Zlib-Trick komprimiert werden, aber es stellt sich heraus, dass das einfache Komprimieren der Ausgabe effizienter ist und das folgende 338-Byte-Programm ergibt (wieder im Base64-Format):
Ich habe auch ein 312-Byte-GZIP-Archiv mit den Texten, das aus demselben DEFLATE-Stream erstellt wurde. Ich nehme an, Sie könnten es ein "zcat-Skript" nennen. :)
quelle
rings
mitrGs
zu speichern 2 charsG
miting,
, aber es stellt sich heraus , dass die Kommas später hinzuzufügen , ist in der Tat kürzer. Vielen Dank!$_
in meinem Update unten vermieden .Common Lisp, 333
363Die eingebauten Funktionen zum Formatieren von Ordnungszahlen sind hilfreich, aber der größte Teil der Komprimierung ergibt sich aus der Möglichkeit, dieselbe Argumentliste immer wieder zu verwenden und bei jedem Durchlauf immer weniger Argumente zu überspringen.
Wie von coredump in den Kommentaren bewiesen, können die eingebauten Einrichtungen für die Kardinäle weiterhin gut genutzt werden.
quelle
(dotimes(n 12)(format t"on-the-~:R-day-of-christmas my-true-love-gave-to-me ~v*~@{~R-~A ~#[AND-~]~}A-PARTRIDGE-IN-A-PEAR-TREE "(1+ n)(- 22 n n)12'drummers-drumming 11'pipers-piping 10'lords-a-leaping 9'ladies-dancing 8'maids-a-milking 7'swans-a-swimming 6'geese-a-laying 5'golden-rings 4'calling-birds 3'french-hens 2'turtle-doves))
Python 2.7 (465)
Ich setze jedoch das 'und' in die gleiche Zeile wie die Tauben anstelle des Rebhuhns.
quelle
JavaScript 570
Ich spiele zum ersten Mal Golf. JavaScript 570
quelle
Rubin (474)
oder in besser lesbarer Form (486):
Hat jemand eine Idee, wie man die .reverse umgehen kann? Ich konnte keine Lösung finden
quelle
12.times
anstatt(0..11).each
; einen einzelnen Puts mit zwei Argumenten anstelle von zwei Puts mit einem Argument ausführen; Verwenden Sie die% w () - Notation für das Array der Weihnachtstage. Zum Schluss können Sie die Umkehrung wieder rückgängig machen, indem Sie die Liste umkehren, ein zusätzliches ^ am Ende der Zeichenfolge[-i..-1]
anfügen und dann anstelle von [0..i] verwenden.Perl,
500,485Dies ist mein erster Versuch und ich bin sicher, dass er viel kürzer gemacht werden könnte. Die Zeilenumbrüche dienen der Lesbarkeit. Es hat drei wichtige Felder, von denen eines den Namen für jeden Tag enthält
@s
, von denen eines alle Geschenke auflistet (mit Ausnahme des ersten)@a
und eines, das auflistet, welche Geschenke bereits gegeben wurden@b
. Der Hauptmechanismus besteht darin, dass jeden Tag@b
ein zusätzliches Geschenk von@a
nach gedruckt und dann übertragen wird@b
.Danke an Andrew für 500-> 485
quelle
rings
mitr$1s
1 mehr Zeichen zu speicherns
als Teil des Variablennamens interpretiert und die Variable$is
nicht existiert. (Sie sind eigentlich ich ist anstelle von denen, übrigens)eigth
->eighth
$i
,$;
um das zu umgehen. Niemand benutzt es jemals$;
für seinen beabsichtigten Zweck.Vim - 578 Tastenanschläge
Ich habe beschlossen, dies zu versuchen und Vim-Golf zu spielen, da dies die Art von Dingen ist, die man mit Vim-Golf spielen kann.
Beginnen Sie mit dem Einfügen des Frameworks - die Zeile "X day of Christmas" insgesamt 12 Mal (89 Tastenanschläge):
Führen Sie dann eine Reihe von Makros aus, in die die Nummern 2 bis 12 an den entsprechenden Stellen eingefügt werden, an denen sie für den Text erforderlich sind (172 Tastenanschläge):
Das "dw" in der zweiten Zeile ist, das erste "und" loszuwerden, weil es dort nicht hingeht.
Führen Sie dann eine Reihe von Substitutionen für die Anzahl der Dinge durch, die die wahre Liebe gegeben hat (319 Tastenanschläge):
Und schließlich jedes Vorkommen von
X
durch eine Ordnungszahl ersetzen :Und wir sind fertig!
Ich bin sicher, dass es noch andere Optimierungen gibt, die ich verpasst habe, aber ich finde das ziemlich gut.
quelle
:%s/2/two turtle doves,
C (644)
Die Anzahl enthält keine für die Präsentation verwendeten Leerzeichen.
Die Ausgabe ist wie folgt:
quelle
Powershell,
487453Vielen Dank an Daan für die Idee, eine verkettete Zeichenfolge zu teilen.
Ich hatte ursprünglich eine switch-Anweisung eingefügt, um das "und" für alle außer dem ersten Vers auf das Rebhuhn zu bekommen. Aber weil die Frage uns von Interpunktion befreit, können wir einfach das "und" an die Tauben anhängen.
Dies führt zu folgenden Zeilenvorschüben:
quelle
Perl, 368
389(kein Unicode / keine Komprimierung)Kabelbäume Lingua :: EN :: Numbers , obwohl ich nicht zu 100% überzeugt bin, ist es eine gute Idee, wenn ich die Länge des Moduls und der Bezeichnernamen sehe. Benötigt Perl 5.10 oder höher, mit einem
-E
Schalter von der Befehlszeile aus ausführen .Bearbeiten: kleinere Verbesserungen: Verwenden Sie kein Array mehr, verwenden Sie
$_
nicht mehr benötigte Leerzeichen besser .quelle
PowerShell, 440
Dies druckt den Text wie in der Frage angegeben mit mehreren Zeilen pro Vers. Wir können ein paar Zeichen speichern, wenn diese Anforderung nicht vorhanden ist.
quelle
C # (528)
quelle
Java, 2062
Ich weiß, dass dies vor einiger Zeit gepostet wurde, aber ich dachte, ich würde es versuchen. Ich bin ein Student und noch neu in diesem Bereich, aber es scheint zu funktionieren.
quelle
Swift, 577
Sie können dies auf einem Spielplatz einfügen.
Ich habe versucht, das
v
in den Druckbefehl zu verschieben und habe:quelle
Ruby 1.9.3, komprimiert, 321 Zeichen
Da der Code nicht druckbare Zeichen enthält, werde ich stattdessen einen Hexdump des Codes veröffentlichen:
Um den eigentlichen Code aus dem Hexdump zu erstellen, legen Sie ihn in eine Datei und führen Sie ihn aus
xxd -r hexdump > 12days.rb
. Dannruby1.9.3 12.days.rb
wird beim Ausführen der Code ausgeführt und der Text gedruckt. Beachten Sie, dass dieser Code Ruby 1.9.3 erfordert (weil er verwendet wirdZlib.inflate
), sodass er mit Ruby 1.8.x, 1.9.1 und 1.9.2 nicht funktioniert.Der unkomprimierte Code ist 425 Zeichen lang:
quelle
Perl, 319/313
Idee: Dekomprimieren und bewerten Sie die Lingua :: EN :: Numbers-Lösung von JB.
Fügen Sie zuerst diesen Textblock in den Befehl ein
perl -e 'use MIME::Base64; print decode_base64 $_ while <>;' >12days.pl
. Führen Sie als Nächstes den Befehl ausperl -M5.01 12days.pl
.Das Skript selbst hat die Form,
use Compress::Zlib;$_='...';eval uncompress$_;
in der...
sich JBs 368 char-Lösung befindet, nachdem es mit diesem Befehl komprimiert und mit einem Escapezeichen versehen wurde'
.Ilmaris Skript beschwert sich darüber, dass ein schreibgeschützter Wert ohne die zusätzlichen
$_=...;
Zeichen geändert wird, aber vermutlich würde er dies 313 machen . Sie könnten mehrere weitere Bytes einsparen, indem Sie die Komprimierung manuell anpassen, wie es Ilmari zuvor getan hat, vielleicht erreichen Sie 310 oder so , aber ich habe mich nicht darum gekümmert.Perl, 376 (betrügt eine andere Vorlage) [meine ursprüngliche Vorlage]
Erstellen Sie zunächst ein Perl-Skript mit dem Namen
12days.pl
:Leiten Sie als Nächstes die Ausgabe einer anderen
12days.txt
Übermittlung an den folgenden Befehl weiter und führen Sie ihn aus:Vola
12days.pl
ist ungefähr 376 Bytes groß und druckt das Lied. ;) Mit rawinflate werden ausgehend von Ilmaris Ausgabe amüsanterweise genau sechs Bytes aus dem Datendokument in den Code verschoben.Ich hatte mich ursprünglich direkt auf die Suche nach einem Huffman-Codierungsmodul gemacht, was bei weitem nicht so unehrlich ist. Leider hat CPAN keine Module mit der englischen Buchstaben-Entropietabelle, was Sie wirklich wollen, wenn Sie sehr kurze Zeichenfolgen komprimieren.
Ich fand, dass
fortune -m Days\ of\ Christmas
das leider auch nicht funktioniert.quelle
PHP, 548
Verkürzte Länge mit Kompression, 502
quelle
VALA,
584, 574Keine Warnung mehr beim Kompilieren.
quelle
Java, 608
Erster Beitrag auf Stack Exchange, zweiter Versuch dieses Problems.
Java ist für Aufgaben wie diese etwas umständlich, aber durch die Verwendung von split konnte der String-Overhead verringert werden.
quelle
/// 439 Bytes
Probieren Sie es online!
Wenn nachfolgende Zeilenumbrüche zulässig sind, können Sie vier Bytes speichern:
Probieren Sie es online!
Erläuterung
/// ist eine Sprache, in der die einzige Operation eine sich selbst ändernde Ersetzung ist. Insbesondere
/abc/xyz/
ersetzt der Befehl alle Instanzen vonabc
mitxyz
im Rest des Quellcodes, einschließlich anderer Ersetzungen. Alle anderen Zeichen werden einfach an STDOUT ausgegeben.Während dies für die Turing-Vollständigkeit ausreicht, besteht das Golfen in /// der Regel darin, mit der beabsichtigten Ausgabe zu beginnen und wiederholte Teilfolgen zu identifizieren, die durch Abkürzungen mit einzelnen Zeichen ersetzt werden können.
\
kann als Escapezeichen in Mustern, Ersetzungen und Literalzeichen verwendet werden, um ein Literal/
oder zu bedeuten\
.Die erste Anweisung ist
/|/\/\//
. Dies bedeutet "alles|
durch//
den Rest des Programms ersetzen ". Dies erspart ein Byte für jede nachfolgende Ersetzung im Programm.Danach werden einige Ersetzungen vorgenommen, um den Text selbst zu komprimieren:
on the
wird^
.day of christmas \n my true love gave to me \n
wird%
.-a-
wird=
.ing
wird&
.even
wird*
.th%
wird+
.^
davor stehen zwei Zeilenumbrüche (die in jedem Vers außer dem ersten vorkommen):
.Anschließend schreiben wir die Texte selbst. Dies geschieht durch Ersetzungen
A
durchK
. Jede Buchstabenersetzung fügt der Ersetzung danach eine Zeile hinzu. Zum BeispielK
repräsentierta partridge in a pear tree
undJ
repräsentierttwo turtle doves \n and K
.Auf diese Weise besteht jeder Vers des Liedes aus:
^
oder:
el*th
)%
A
durchgehender Buchstabe stehtK
für den richtigen Text.Da jedoch die meisten Ordnungszahlen auf enden
th
, verwenden wir die Ersetzungth%
→+
, um einige Bytes zu sparen.quelle
Es gibt Zeiten, in denen die naheliegendste Lösung auch die kürzeste ist, dh ich konnte diesem Drang nicht länger widerstehen.
Bash unter Mac OS X, 26
Perl, 111
Eine neue Zeile zur besseren Lesbarkeit hinzugefügt.
quelle
eval compress
Trick verschleiern könnte, um zu behaupten, ich hätte einen Regex gefunden, der sich wirklich gut komprimieren lässt, der aber rund 200 Zeichen aufblähte. lolJava - 1329 Zeichen
Ich bin zu faul, um es zu entgolfen, aber es ist hier: http://ideone.com/MU9IcP .
quelle
EINFACH , 1 Byte
Hinweis :
Die Sprache wurde nach der Herausforderung entworfen und ist immer noch eine WIP.
Wie :
Jedes Zeichen gibt die 12 Weihnachtstage aus.
quelle