Je pensais que ce serait un défi amusant pour tout le monde et je suis curieux de voir les solutions que les gens trouvent.
Imprimer les paroles de "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.
Règles
- Vous n'avez pas à vous soucier de la capitalisation; le texte entier peut être insensible à la casse
- Vous pouvez sensiblement ignorer toute ponctuation: les tirets peuvent être des espaces et les virgules et les points peuvent être ignorés
- Il devrait y avoir une ligne vierge entre chaque verset
- Vous devez ordinaliser vos numéros: " premier jour de Noël", " quatre oiseaux qui appellent", etc.
Réponses:
Brainfuck - 2,974
Je suis plutôt fier de celui-ci. Cela ressemble à un assez grand nombre, mais gardez à l'esprit que je n'ai utilisé aucune bibliothèque de compression externe et aucun du texte d'origine n'est dans mon programme. Aucune des autres communications ne peut le dire. Tout est codé à la main. Des générateurs de texte plus naïfs donnent plus de 39 Ko pour ce texte, donc je dirais que c'est une amélioration significative.
Malheureusement, c'est environ 600 caractères de plus que sa propre sortie, mais peu importe. Il conserve les caractères c, h, m, r, w dans un tableau et l'utilise pour imprimer tout le texte. Deux tableaux à droite de douze espaces gardent une trace de quel jour nous sommes pour le décompte et pour quels éléments nous pouvons sortir. Je peux peut-être l'optimiser un peu en réorganisant la carte mémoire pour amener les caractères d'impression entre les deux tableaux de comptage pour éviter de si longues chaînes de
<<<<<<<
et>>>>>>
, mais ce serait beaucoup de travail à ce stade. Je pourrais aussi probablement choisir de meilleurs caractères de départ avec une analyse de fréquence pour minimiser l'incrémentation / décrémentation, mais peu importe.Cela dépend des cellules d'encapsulation 8 bits pour fonctionner correctement.
Non golfé:
la source
Perl,
438291 caractèresInspiré par l'utilisation de la compression DEFLATE par Jeff Burdges , le code Ruby compressé de Ventero et l'utilisation de Lingua :: EN :: Numbers par JB , j'ai réussi à compresser mon entrée à 291 caractères (enfin, octets), y compris le code de décompression. Étant donné que le programme contient des caractères non imprimables, je l'ai fourni au format MIME Base64 :
Pour désencoder le programme, vous pouvez utiliser le script Perl d'assistance suivant:
Enregistrez la sortie dans un fichier nommé
12days.pl
et exécutez-le avecperl -M5.01 12days.pl
. Comme indiqué, vous devez avoir installé le module Lingua :: EN :: Numbers pour que le code fonctionne.Au cas où vous vous poseriez la question, la partie lisible du code ressemble simplement à ceci:
où
...
représente 254 octets de code Perl compressé RFC 1950 . Non compressé, le code contient 361 caractères et ressemble à ceci:L'écriture de ce code était un type étrange d'exercice de golf: il s'avère que la répétition maximisée et la minimisation du nombre de caractères distincts utilisés sont beaucoup plus importantes que la minimisation du nombre de caractères bruts lorsque la métrique pertinente est la taille après compression .
Pour extraire les derniers caractères, j'ai écrit un programme simple pour essayer de petites variations de ce code pour trouver celui qui compresse le mieux. Pour la compression, j'ai utilisé l' utilitaire KZIP de Ken Silverman , qui donne généralement de meilleures rations de compression (au prix de la vitesse) que le Zlib standard, même avec les paramètres de compression maximum. Bien sûr, puisque KZIP crée uniquement des archives ZIP, j'ai dû ensuite extraire le flux DEFLATE brut de l'archive et l'envelopper dans un en-tête et une somme de contrôle RFC 1950. Voici le code que j'ai utilisé pour cela:
Si cela ressemble à un horrible kluge, c'est parce que c'est exactement ce que c'est.
Pour l'intérêt historique, voici ma solution originale de 438 caractères, qui génère une sortie plus agréable, y compris les sauts de ligne et la ponctuation:
Faits saillants de cette version la paire de regexps
s/e?t? .*/th/,s/vt/ft/
, qui construisent les ordinaux pour 4 à 12 à partir des cardinaux au début des lignes de cadeaux.Ce code peut, bien sûr, également être compressé à l'aide de l'astuce Zlib décrite ci-dessus, mais il s'avère que la simple compression de la sortie est plus efficace, produisant le programme suivant de 338 octets (au format Base64, encore):
J'ai également une archive gzip de 312 octets des paroles, construite à partir du même flux DEFLATE. Je suppose que vous pourriez l'appeler un "script zcat". :)
la source
rings
parrGs
pour enregistrer 2 caractèresG
paring,
, mais il s'avère que l'ajout de virgules plus tard est en effet plus court. Merci!$_
dans ma mise à jour ci-dessous.Lisp commun,
333363Les fonctionnalités intégrées pour formater les ordinaux sont utiles, mais la majeure partie de la compression provient de la possibilité d'utiliser la même liste d'arguments encore et encore, en sautant de moins en moins d'arguments à chaque exécution.
Comme l'a démontré coredump dans les commentaires, les installations intégrées peuvent toujours être utilisées à bon escient pour les cardinaux.
la source
(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))
JavaScript 570
C'est ma première fois au golf. JavaScript 570
la source
Python 2.7 (465)
Cependant, je mets le «et» sur la même ligne que les colombes au lieu de la perdrix.
la source
Rubis (474)
ou sous une forme plus lisible (486):
quelqu'un a une idée de la façon de contourner le .reverse? je n'ai pas pu trouver de solution
la source
12.times
au lieu de(0..11).each
; faire un seul put avec deux arguments au lieu de deux put avec un argument; utilisez la notation% w () pour le tableau des jours de Noël. Enfin, vous pouvez vous débarrasser de l'inverse en inversant la liste, en ajoutant un ^ supplémentaire à la fin de la chaîne, puis en utilisant[-i..-1]
au lieu de [0..i].Perl,
500485C'est ma première tentative, et je suis sûr qu'elle pourrait être beaucoup plus courte. Les sauts de ligne sont pour la lisibilité. Il a trois tableaux importants, dont l'un contient le nom de chaque jour
@s
, dont l'un répertorie tous les cadeaux (sauf le premier)@a
, et celui qui répertorie les cadeaux qui ont déjà été offerts@b
. Le mécanisme principal est que chaque jour, il imprime@b
puis transfère un cadeau supplémentaire de@a
à@b
.Merci à Andrew pour 500-> 485
la source
rings
parr$1s
pour enregistrer 1 char de pluss
comme faisant partie du nom de la variable, et la variable$is
n'existe pas. (Ce sont en fait des i au lieu de ceux, btw)eigth
->eighth
$i
, disons,$;
pour contourner cela. De toute façon, personne ne l'utilise$;
aux fins prévues.Vim - 578 frappes
J'ai décidé d'essayer le vim-golf, car c'est le genre de chose qui peut être vim-golf.
Commencez par insérer le cadre - la ligne "X jour de Noël" au total 12 fois (89 frappes):
Ensuite, effectuez une série de macros qui insèreront les nombres 2 à 12 aux endroits respectifs dont ils ont besoin pour les paroles (172 frappes):
Le "dw" sur la deuxième ligne est de se débarrasser du premier "et", car il n'y va pas.
Ensuite, effectuez une série de substitutions pour le nombre de choses que le véritable amour a donné (319 frappes):
Et enfin, en remplaçant chaque occurrence de
X
par un nombre ordinal:Et nous avons terminé!
Je suis sûr qu'il y a d'autres optimisations que j'ai ratées, mais je pense que c'est assez bien moi-même.
la source
:%s/2/two turtle doves,
C (644)
Le nombre ne comprend pas les espaces utilisés pour la présentation.
La sortie est comme:
la source
Powershell,
487453Merci de Daan pour l'idée de fractionner une chaîne concaténée.
J'avais à l'origine inclus une instruction de commutation pour obtenir le "et" sur la perdrix pour tous sauf le premier couplet. Mais, parce que la question nous absout de la ponctuation, nous pouvons simplement ajouter le «et» aux colombes.
Il en résulte des sauts de ligne comme suit:
la source
Perl, 368
389(pas d'unicode / compression)Harnesses Lingua :: FR :: Numbers , même si je ne suis pas convaincu à 100% que c'est une bonne idée quand je vois le module et la longueur des noms de ses identifiants. Nécessite Perl 5.10 ou une version ultérieure, exécutée à partir de la ligne de commande avec un
-E
commutateur.Edit: améliorations mineures: arrêtez d'utiliser un tableau, meilleure utilisation
$_
des espaces blancs inutiles.la source
PowerShell, 440
Cela imprime les paroles comme indiqué dans la question avec plusieurs lignes par verset. Nous pouvons enregistrer quelques caractères si cette exigence n'est pas là.
la source
C # (528)
la source
Java, 2062
Je sais que cela a été publié il y a quelque temps, mais j'ai pensé que j'essaierais. Je suis étudiant et encore nouveau dans ce domaine, mais cela semble fonctionner.
la source
Swift, 577
Vous pouvez coller cela dans une aire de jeux.
J'ai essayé de déplacer le
v
dans la commande d'impression et j'ai obtenu:la source
Ruby 1.9.3, compressé, 321 caractères
Étant donné que le code contient des caractères non imprimables, je publierai plutôt un vidage hexadécimal du code:
Pour créer le code réel à partir de l'hexdump, placez-le dans un fichier et exécutez
xxd -r hexdump > 12days.rb
. L'exécutionruby1.9.3 12.days.rb
exécutera ensuite le code et imprimera les paroles. Notez que ce code nécessite Ruby 1.9.3 (car il utiliseZlib.inflate
), donc il ne fonctionnera pas avec Ruby 1.8.x, 1.9.1 et 1.9.2.Le code non compressé comprend 425 caractères:
la source
Perl, 319/313
Idée: décompresser et évaluer la solution Lingua :: EN :: Numbers de JB.
Tout d'abord, collez ce bloc de texte dans la commande
perl -e 'use MIME::Base64; print decode_base64 $_ while <>;' >12days.pl
. Ensuite, exécutez la commandeperl -M5.01 12days.pl
.Le script lui-même prend la forme
use Compress::Zlib;$_='...';eval uncompress$_;
où se...
trouve la solution 368 char de JB après avoir été compressé avec cette commande et avoir échappé à a'
.Le script d'Ilmari se plaint de modifier une valeur en lecture seule sans les
$_=...;
caractères supplémentaires , mais il ferait probablement ce 313 . Vous pouvez économiser plusieurs octets supplémentaires en modifiant manuellement la compression comme Ilmari l'a fait auparavant, atteignant peut-être 310 ou plus , mais je n'ai pas pris la peine.Perl, 376 (tromper une autre soumission) [ma soumission d'origine]
Tout d'abord, créez un script perl appelé
12days.pl
contenant:Ensuite, dirigez la sortie de toute autre soumission vers
12days.txt
et exécutez la commande:Vola
12days.pl
fait environ 376 octets et imprime la chanson. ;) L'utilisation amusante de rawinflate déplace précisément six octets du document de données dans le code à partir de la sortie d'Ilmari.À l'origine, je m'étais mis à la recherche d'un module de codage Huffman directement, ce qui n'est pas si malhonnête. Pourtant, malheureusement, CPAN n'a pas de modules avec la table d'entropie des lettres en anglais, ce que vous voulez vraiment lors de la compression de chaînes très courtes.
J'ai trouvé que
fortune -m Days\ of\ Christmas
cela ne fonctionnait pas non plus, malheureusement.la source
PHP, 548
Longueur réduite avec compression, 502
la source
VALA,
584, 574Plus d'avertissement à la compilation.
la source
Java, 608
Premier post sur Stack Exchange, deuxième tentative de ce problème.
Java est un peu lourd pour des tâches comme celle-ci, mais l'utilisation de split a permis de réduire la surcharge de String.
la source
/// , 439 octets
Essayez-le en ligne!
Si les retours à la ligne de fin sont autorisés, vous pouvez enregistrer quatre octets:
Essayez-le en ligne!
Explication
/// est un langage où la seule opération est une substitution auto-modifiable. En particulier, l'instruction
/abc/xyz/
remplace toutes les instances deabc
parxyz
dans le reste du code source, y compris les autres substitutions. Tout autre caractère est simplement sorti vers STDOUT.Bien que cela soit suffisant pour que Turing soit complet, le golf dans /// consiste généralement à commencer par la sortie prévue et à identifier les sous-chaînes répétées qui peuvent être remplacées par des raccourcis à un seul caractère.
\
peut être utilisé comme caractère d'échappement dans les motifs, les remplacements et les caractères littéraux pour signifier un littéral/
ou\
.La première instruction rencontrée est
/|/\/\//
. Cela signifie "remplacer tout|
par//
dans le reste du programme». Cela enregistre un octet pour chaque substitution ultérieure dans le programme.Après cela, un ensemble de remplacements est effectué pour compresser le texte lui-même:
on the
devient^
.day of christmas \n my true love gave to me \n
devient%
.-a-
devient=
.ing
devient&
.even
devient*
.th%
devient+
.^
précédé de deux nouvelles lignes (qui apparaît dans tous les versets sauf le premier) devient:
.Ensuite, nous écrivons les paroles elles-mêmes. Cela se fait à l' aide de remplacement
A
parK
. Chaque remplacement de lettre ajoute une ligne au remplacement après celui-ci. Par exemple,K
représentea partridge in a pear tree
etJ
représentetwo turtle doves \n and K
.De cette façon, chaque couplet de la chanson est composé de:
^
ou:
el*th
)%
A
parK
qui représente les paroles correctes.Cependant, comme la plupart des ordinaux se terminent par
th
, nous utilisons la substitutionth%
→+
pour enregistrer quelques octets.la source
Il y a des moments où la solution la plus évidente est aussi la plus courte, c'est-à-dire que je ne pouvais plus résister à cette envie.
Bash sur Mac OS X, 26
Perl, 111
Une nouvelle ligne ajoutée pour plus de lisibilité.
la source
eval compress
astuce pour prétendre avoir trouvé une expression régulière qui comprime très bien, mais qui gonflait environ 200 caractères. lolJava - 1329 caractères
Je suis trop paresseux pour le dé-golfer, mais c'est ici: http://ideone.com/MU9IcP .
la source
SIMPLE , 1 octet
Remarque :
Le langage a été conçu après le défi et est toujours un WIP.
Comment :
Tout personnage affichera les 12 jours de Noël.
la source