Randall Munroe (auteur de XKCD) a organisé une enquête pour donner des noms aux couleurs . Le résultat principal est une liste de noms pour les 954 couleurs de moniteur RVB les plus courantes .
Pour faciliter la programmation, voici la liste en texte brut: http://xkcd.com/color/rgb.txt . Attention, la première ligne n'est pas data, mais contient la licence.
Ecrivez un programme ou une fonction prenant comme entrée un nom de couleur valide de la liste ci-dessus et générant le code de couleur RVB associé. Votre programme n'a pas à gérer des entrées non valides de quelque manière que ce soit.
Les failles standard s'appliquent. De plus, votre réponse ne doit pas utiliser de mappes de nom de couleur <-> prédéfinies (intégrées ou externes). (Cela inclut la liste liée.) Le code le plus court en octets gagne. Si vous lisez à partir d'un fichier, le nombre d'octets du fichier doit être inclus.
Exemples:
dark peach -> #de7e5d
robin's egg blue -> #98eff9
pink/purple -> #ef1de7
shit #7f5f00
-bubble gum pink #ff69af
,bubblegum pink #fe83cc
Réponses:
Perl 5 -
421239563930407 octets pour le code et 3523 pour le fichier de données. Les données binaires sont lues dans le fichier 'g', un hexdump peut être trouvé ici .
Cela utilise une fonction de hachage parfaite générée à l'aide de GNU gperf , qui attribue à chaque nom de couleur un entier unique compris entre 0 et 6304 pouvant être utilisé pour indexer une table. Les données gzippées contiennent les valeurs de couleur au format 1 octet indiquant le décalage dans le tableau par rapport à la couleur précédente, puis 3 octets pour la couleur elle-même (avec deux chiffres hexadécimaux par octet). (0 octet pour le décalage signifie que c'est en fait la valeur suivante + 255, car tous les décalages ne tiennent pas dans un octet).
Le code analyse les données pour créer la table contenant la chaîne de couleur rgb, puis applique la fonction de hachage (traduite en perl) à l'entrée pour sélectionner la sortie correspondante dans la table.
Usage:
Edit: Réduit encore la taille en compressant le fichier de données
la source
EXCEL, 18 (+ 18269)
Juste pour définir une base de référence, je vais montrer la solution Excel la plus simple à laquelle je puisse penser:
Code
Le code dans Excel est très simple:
L'entrée doit être placée entre les guillemets.
Les données
Les données doivent être stockées dans un fichier .csv, ressemblant grossièrement à ceci:
Lorsque je clique sur le fichier CSV, il ouvre automatiquement Excel et place les données dans les colonnes A et B, vous aurez peut-être besoin d'un séparateur différent.
la source
Ruby, 5
37988 + 9 + 5 220 = 5 317 octets+9 octets pour le
-rdigest
drapeau.... plus un dictionnaire de 5 220 octets sous forme de données binaires lues à partir de STDIN (ou argument de nom de fichier). Vous trouverez le dictionnaire au format xxd dans l'extrait ci-dessous. Le programme prend un nom de couleur en tant qu'argument, vous l'invoquez ainsi:
Si quelqu'un peut trouver un moyen plus court de lire un fichier et de prendre un nom de couleur comme argument, laissez un commentaire.
$*
(ARGV) et$<
(ARGF) interagissent de manière étrange et occulte, ergo$*.pop
.Dictionnaire (format xxd)
Afficher l'extrait de code
Explication
Encodage du dictionnaire
La construction du dictionnaire est très simple. Je prends le hachage MD5 hexadécimal du nom de la couleur et concatène les deuxième au sixième chiffres hexadécimaux (qui sont uniques pour chaque couleur) avec le code de couleur à 6 chiffres. Je les joint en une seule chaîne de 10 439 chiffres hexadécimaux. Ensuite, je convertis cela en l’équivalent de 5 219,5 octets, avec des zéros à droite pour un nombre égal à 5 220 octets.
Chose amusante: j'ai essayé de compresser le dictionnaire avec Gzipping et j'ai même
zopfli -i100
créé un fichier 40 octets plus volumineux . Juste pour le plaisir, j’ai calculé l’entropie du dictionnaire binaire et c’est 99,8% (contrergb.txt
61,2% , par exemple ). Pas mal!Voici le code qui génère le dictionnaire:
Décodage et recherche dans le dictionnaire
C'est l'opposé de ce qui précède. Premièrement, je convertis les données binaires en une représentation hexadécimale de 10 439 chiffres. Ensuite, je prends la chaîne d'entrée (nom de couleur) et j'obtiens les deuxième au sixième chiffres hexadécimaux de son hachage MD5 et j'utilise une expression régulière pour trouver ces chiffres dans la chaîne hexadécimale de 10 439 chiffres à un indice divisible par 11, puis je retourne les 6 chiffres suivants. , qui sont le code de couleur correspondant. Par exemple, pour le hachage
b9ca5
( « bleu nuageux »), l'expression régulière suivante est construite:/^.{11}*b9ca5\K.{6}/
. L'\K
opérateur rejette la correspondance jusqu'à ce point, de sorte que seuls les six derniers caractères sont renvoyés.la source
pink/purple
est is#a6814c
, mais la bonne réponse est#ef1de7
.Perl, 7 375 octets
Stocke les données légèrement compressées (
grey
->E
, etc.) sous forme de données binaires compressées, les développe dans un hachage et renvoie la clé correspondante après avoir remplacé les espaces dans l'entrée par_
. Je ne pense pas que ce soit génial, et je suis certain que d’autres disposeront de méthodes beaucoup plus intelligentes pour compresser les données. Je pourrais peut-être jouer à cela plus tard.Un hexdump réversible est disponible ici et a été généré à l'aide de ce script .
Usage
la source
Ruby,
1213112030 +-p
= 12033 octetsLe nombre d'octets est après remplacement
<compressed text>
par les données de collage brutes dans http://pastebin.com/xQM6EF9Q . (Assurez-vous d'obtenir les données brutes à cause des onglets dans le fichier)Je pourrais vraiment réduire davantage le texte, mais cela fait maintenant quelques heures que je suis à la tâche et j'ai besoin de dormir.
L'entrée est une ligne d'entrée de STDIN sans nouvelle ligne. Ajout en fin de ligne nécessite +3 octets en changeant
($_+?\t)
à(chomp+?\t)
.la source
BASH + bzip2,
805868096797 octetsStocké la liste d'origine dans un fichier après l'avoir compressé, ne sachant pas si cela est autorisé.
Appeler avec:
la source
dusty teal
-à- dire échouer. Lire tous les arguments avec$*
ou quelque chose comme ça.bzgrep ..... c
placePython, 9360 caractères
N'utilise aucune bibliothèque de compression. Je vais le laisser un peu mystérieux pendant un moment sur la façon dont cela fonctionne, puis publier un lien vers la technique. Bien sûr, il pourrait être raccourci en stockant les données dans un format binaire, mais c’est un exercice pour une autre fois.
Explication:
Utilise une adaptation du code de http://stevehanov.ca/blog/index.php?id=119 pour générer une recherche de hachage parfaite et minimale, des noms de couleurs aux codes de couleurs.
la source
Python 3, 4927
182 code + 4745 fichier de données
Théorie de fonctionnement:
md5((67*s).encode('ascii')).digest()[5:7]
est un hachage parfait des noms de couleurs à une valeur de 2 octets. Le fichier de données binaire est simplement une liste de morceaux de 5 octets - un hachage de 2 octets et une couleur de 3 octets. Le code hache le nom de la couleur d'entrée et recherche dans les données pour trouver une correspondance.Le code pour générer le fichier binaire:
Voici le code que j'ai utilisé pour trouver un hachage parfait. Rien d'extraordinaire, juste trois boucles imbriquées: nombre de fois pour répéter le nom (par exemple, "blue", "blueblue", ...); les algorithmes de hachage disponibles; et les décalages dans les hachages. Il imprime des combinaisons pour lesquelles il n'y a pas de collision.
la source
Python 3, 296 + 3960 = 4256 octets
Je ne l'ai pas utilisé
gperf
car ce serait trop ennuyeux de répéter ce truc. Au lieu de cela, j'ai fait une solution de force brute à partir de zéro et donc la taille n'est pas optimale (mais pas trop mal, aussi).Cependant, j'ai trouvé comment compresser les couleurs plus efficacement: elles sont triées et alignées sur 4 octets. LZMA en profite. (les couleurs sont compressées à 2180 octets)
Pour rechercher la couleur par son nom, une fonction de hachage de 15 bits est utilisée. Théoriquement, il pourrait être trouvé avec moins de bits (les nombres 0..949 peuvent être codés avec 10 bits), mais mon ordinateur ne pouvait rien trouver de mieux, c'est trop de travail.
Le code prend l’entrée de stdin et imprime la réponse.
Le code:
Fichier de données (binaire, doit être nommé
a
et placé dans le même dossier):Comment courir:
la source
C, 19 566 octets
Un misérable 19 566 octets.
Bog-standard C. Le fichier rgb.txt est acheminé via stdin. La couleur à trouver est donnée comme premier argument.
Alors:
./xkcd "bright sea green" < colors.txt
Donne:
bright sea green -> #05ffa6
la source
Java,
7 9787 435 octetsLe code est 293 octets, les données sont 7,142 octets
Golfé:
Ungolfed:
Le fichier nommé "c" dans le programme est le résultat de l'opération inverse de ce programme: prenez le code de hachage de chaque clé dans le fichier d'entrée et stockez-le avec la représentation entière de la valeur de couleur. Cela va dans un flux de sortie objet, un flux de sortie GZip, puis un flux de sortie de fichier. Ce programme le lit à travers les flux d'entrée inverses.
Les codes de hachage Java par défaut de toutes les couleurs sont uniques dans cet ensemble de données, ce qui en fait une bonne clé 32 bits dans la carte de hachage. La valeur est déjà un entier. Il suffit donc de la formater correctement en tant que chaîne hexagonale, complétée à six chiffres si nécessaire, avec un signe dièse devant.
la source
Java, 4649 octets
Code Java: 497 octets, fichier de données: 4152 octets
Le fichier peut être trouvé ici
ungolfed:
Le programme utilise une version améliorée du code de hachage Java qui utilise seulement 17 bits:
Les couleurs sont triées par composant bleu croissant. Ils sont stockés sur 18 bits: 8 pour le rouge, 8 pour le vert et 2 pour le bleu delta.
Taille totale du fichier: 949 couleurs * (18 + 17) = 33 215 = 4152 octets
la source
JavaScript (Node.js), 10785 octets
Usage:
Données encodées .
la source
MATLAB, 94 + 7.243 = 7.337 octets
Générez le fichier MAT "h.mat" avec la variable "c" contenant une liste triée des sommes de contrôle CRC32 des noms (c = java.util.zip.CRC32; c.update (uint8 (x)); c.getValue ();) et la même liste triée des codes hexadécimaux convertis des couleurs (sscanf (x (:, fin), '% x')) en tant que "e". Cela devrait avoir (R2013b, format de fichier v7, une taille de 7.243 octets).
La fonction est la suivante
Il tire parti de la compression intégrée des fichiers MAT et de la prise en charge de Java pour la fonction CRC32.
la source
Go, 6709 octets
Le code est de 404 octets, les données sont de 6305 octets
Les données sont codées avec
xxd -p
. Extraire dans un fichier simplement nomméf
avecxxd -r paste f
. Le code peut être exécuté commego run file.go "tree green"
la source
C #, 6422 octets
Le code est de 575 octets, les données sont de 5847 octets
Les données existent dans un fichier GZipped adjacent qui contient une représentation transformée des données d'origine. Les mots de couleur qui apparaissent plus d'une fois sont extraits et placés dans un tableau d'en-tête en haut du fichier, préfixé par une longueur d'un octet.
Les entrées de données (après l'en-tête) consistent en un ensemble de:
Chaque entrée se termine par 0xFF, 0xFE, 0xFD, qui indique que les octets suivants, un, deux ou trois, représentent respectivement le décalage de la valeur de la couleur.
La table est analysée dans l'ordre et la valeur de couleur est accumulée jusqu'à ce qu'une chaîne correspondante à l'entrée soit trouvée.
Code de décompression / consultation réduit:
Code de compression de données
la source
C # 7 209 octets: 6 643 octets données + 566 octets de code (878 octets non minimisés)
Le dépôt Github est ici: https://github.com/nbcarey/color-map
Les noms de couleur sont compressés dans le fichier de données à l'aide du hachage FNV-32-1a, car cet algorithme de hachage est sans collision pour cet ensemble de noms de couleur. Ainsi, chaque nom de couleur est stocké sous forme de 4 octets.
Chaque couleur est stockée sous forme de 3 octets (1 pour le rouge, le vert et le bleu). Pas de magie là-bas.
Par conséquent, chaque mappage du nom de couleur sur la valeur RGV occupe 7 octets dans le fichier compressé.
Il s'agit d'une version d'une ligne du hachage FNV-32-1a (en supposant une chaîne contenant uniquement des caractères ASCII simples:
Ce fichier de données compressé se trouve dans le dépôt github à l’ adresse https://github.com/nbcarey/color-map/blob/master/color-map/hashed-color-map.dat.
Voici le code minimisé:
Et voici un code lisible par l'homme:
la source
PHP, 5014 octets
Pas le meilleur qui soit, mais il est tard et j'ai besoin de dormir un peu. :-)
La beauté de PHP réside dans le fait que vous pouvez intégrer des données utiles dans votre script et lire le fichier lui-même, ce qui rend le script autonome. Il suffit de télécharger , lancez - le et il vous demandera le nom de la couleur.
L'astuce de base consiste ici à hacher les noms de couleur et à générer des sous-chaînes d'identification minimale de ce hachage. J'ai trouvé qu'il suffisait de 4 caractères d'un hachage SHA1, les 3 premiers et le 17ème pour identifier toutes ces couleurs de manière unique. La clé est en binaire ainsi que le code de couleur, qui correspond à un octet par canal de couleur. Chaque entrée occupe donc 5 octets, ce qui donne une charge utile de 5 x 949 = 4745 octets (le nombre magique que vous voyez dans le code).
La compression n'a pas beaucoup aidé, bzip2, LZMA a tous créé des fichiers plus volumineux, donc sans autres astuces, cette opération est aussi compressée que dans cette approche.
la source
Bash + (coreutils, gzip, xxd, openssl, sed, grep), 4946 octets
données: 4482 octets, code: 464 octets
Les données peuvent être trouvées en base64 ici . Je sais que le code peut être plus joué au golf. Trop endormi maintenant: / Toutes les suggestions sont les bienvenues :-)
Explication
Voici les actions que j'ai effectuées sur le fichier d'origine après la suppression du commentaire de licence.
openssl dgst -md5 -binary|base64
base64
utilise un ensemble de 64 caractères pour représenter les donnéesA-Za-z0-9+/
,. Donc, j'espérais trouver 2 octets car toutes les entrées étaient 494 et 64 * 64 = 4096 mais je n'en trouvais aucune. J'ai également essayé de trouver des entrées uniques à 2 caractères en utilisant la premièresha512
étape, mais sans aucune chance. Donc, je suis resté avec ces 3 octets pour les noms de couleurs.(echo '0:';echo -n "$line"|cut -d '#' -f 2)|xxd -rp -l 16|base64
zopfli -i1000
de compresser le fichier.Donc, le fichier de résultat avant la compression ressemblerait à ça:
J'ai essayé d' autres utilitaires de compression aussi , mais avec moins bons résultats , à l' exception de
zopfli -i0000 --zlib
avec 4470 octets etzopfli -i10000 --defalte
avec 4464 , mais je ne suis pas sûr de savoir comment il décompresse formats.Afin de trouver le code de couleur, je fais les actions inverses. Je crée le code à 3 caractères à partir du nom donné et je reconstruis partiellement les codes de couleur d'origine. Par exemple pour
adobe
je crée tout ce qui commence parX
:Ensuite, je grep la
Xqy
ligne et retourne la deuxième partie qui est la couleur hexadécimale.J'ai vraiment apprécié ce casse-tête et il y a beaucoup de bonnes réponses ici. Merci et bon travail à tous!
la source
Bash + coreutils / xxd, 4064 octets
Données 3796 octets (vidage hexadécimal du fichier de données)
Bash 268 octets
Ungolfed
L'idée générale est de parcourir les champs 32 bits, de trouver le hachage unique 14 bits correspondant et d'imprimer le code de couleur à cet emplacement. L'encodage couleur 18 bits exploite l'approche de Super Chafouin.
Le hachage unique de 14 bits commence par un sous-ensemble de 14 des bits du md5sum de 128 bits. Pour trouver ces bits, j'ai utilisé un algorithme génétique codé en C ++ ici . Le code pré-charge un fichier fixe appelé "data", qui est simplement le md5sum, un par ligne, en binaire. Si vous avez besoin de cela dans le formulaire de recette, cela créera le fichier de données:
Je trouve le meilleur candidat 14 bits (que j'ai vu jusqu'ici) de ce code dans la génération 2, mais cet ensemble a deux collisions. Plus précisément: "boue" et "violet pâle" correspondent à la même valeur, et "bleu aqua" et "vert clair" à la même valeur. Puisqu'il n'y a que deux collisions et que je n'ai rien trouvé de mieux, je les homonymie; s'avère que la moitié de chacune de ces valeurs de compartiment est inutilisée.
J'ai déjà essayé la compression sur d; mais ni bzip2, ni gzip, ni xz ne semble réduire sa taille.
la source
Groovy,
153 + 10 697 = 10 850253 + 9870 = 10 123 octetsJ'ai décidé que je voulais une solution ne comportant qu'un seul fichier. J'ai donc codé (au coût évident d'espace) une version GZIPped CSV des données en caractères Unicode 0x0020-0x007E (qui, je suppose, serait un codage en base 95?). Le code est de 253 caractères, le contenu de la chaîne est de 10123 caractères.
Pour la lisibilité, voici la même chose avec le texte encodé exclu:
Ma solution d'origine était un encodage plus simple en Base 64 utilisant l'encodeur intégré.
Pour la lisibilité, voici la même chose avec le texte exclu:
la source