Randall Munroe (autor de XKCD) realizó una encuesta para dar nombres a los colores . El resultado principal es una lista de nombres para los 954 colores de monitor RGB más comunes .
Para facilitar la programación, aquí está la lista en texto plano: http://xkcd.com/color/rgb.txt . Cuidado, la primera línea no son datos, pero contiene la licencia.
Escriba un programa o función que tome un nombre de color válido de la lista anterior como entrada y envíe el código de color RGB asociado. Su programa no tiene que manejar entradas inválidas de ninguna manera definida.
Se aplican lagunas estándar. Además, su respuesta no debe usar códigos de color predefinidos (integrados o externos) <-> mapas de nombres de colores. (Esto incluye la lista vinculada). El código más corto en bytes gana. Si lee de un archivo, se debe incluir el recuento de bytes del archivo.
Ejemplos:
dark peach -> #de7e5d
robin's egg blue -> #98eff9
pink/purple -> #ef1de7
shit #7f5f00
-bubble gum pink #ff69af
,bubblegum pink #fe83cc
Respuestas:
Perl
5-421239563930407 bytes para el código y 3523 para el archivo de datos. Los datos binarios se leen desde el archivo 'g', cuyo hexadecimal se puede encontrar aquí .
Utiliza una función hash perfecta generada con GNU gperf , que asigna cada nombre de color a un entero único en el rango de 0 a 6304 que se puede usar para indexar una tabla. Los datos comprimidos contienen los valores de color en el formato de 1 byte que indica el desplazamiento en la tabla del color anterior, luego 3 bytes para el color en sí (con dos dígitos hexadecimales por byte). (Un byte 0 para el desplazamiento significa que en realidad es el siguiente valor + 255, ya que no todos los desplazamientos caben en un byte).
El código analiza los datos para crear la tabla que contiene la cadena de color rgb, luego aplica la función hash (traducida a perl) a la entrada para seleccionar la salida coincidente de la tabla.
Uso:
Editar: redujo aún más el tamaño al comprimir el archivo de datos
fuente
EXCEL, 18 (+ 18269)
Solo para establecer una línea de base, mostraré la solución de Excel más simple que se me ocurrió:
Código
El código en Excel es muy simple:
La entrada debe colocarse entre comillas dobles.
Datos
Los datos deben almacenarse en un archivo .csv, con un aspecto similar al siguiente:
Cuando hago clic en el archivo CSV, se abre automáticamente Excel y coloca los datos en las columnas A y B, es posible que necesite un separador diferente.
fuente
Rubí,
5.37988 + 9 + 5.220 = 5.317 bytes+9 bytes para
-rdigest
bandera.... más un diccionario de 5.220 bytes como datos binarios leídos de STDIN (o argumento de nombre de archivo). Encontrarás el diccionario en formato xxd en el fragmento a continuación. El programa toma un nombre de color como argumento, por lo que lo invoca así:
Si alguien puede encontrar una forma más corta de leer un archivo y tomar un nombre de color como argumento, deje un comentario.
$*
(ARGV) y$<
(ARGF) interactúan de formas extrañas y ocultas, ergo$*.pop
.Diccionario (formato xxd)
Mostrar fragmento de código
Explicación
Codificando el diccionario
La construcción del diccionario es muy simple. Tomo el hash MD5 hexadecimal del nombre del color y concateno los dígitos hexadecimales segundo a sexto (que resultan ser únicos para cada color) con el código de color de 6 dígitos. Los sumo en una sola cadena de 10,439 dígitos hexadecimales Luego convierto esto en el equivalente a 5,219.5 bytes, rellenado con ceros a la derecha para incluso 5,220 bytes.
Lo gracioso: intenté descomprimir el diccionario e incluso produje
zopfli -i100
un archivo 40 bytes más grande . Solo por diversión, calculé la entropía del diccionario binario y es del 99.8% (en comparación, por ejemplo, conrgb.txt
el 61.2%). ¡No está mal!Aquí está el código que genera el diccionario:
Decodificando y buscando el diccionario
Esto es exactamente lo contrario de lo anterior. Primero convierto los datos binarios a su representación hexadecimal de 10,439 dígitos. Luego tomo la cadena de entrada (nombre de color) y obtengo del segundo al sexto dígitos hexadecimales de su hash MD5 y uso una expresión regular para encontrar esos dígitos en la cadena hexadecimal de 10,439 dígitos en algún índice divisible por 11 y devuelvo los 6 dígitos posteriores , que son el código de color correspondiente. Por ejemplo, para el hash
b9ca5
( "azul nublado"), la siguiente expresión regular se construye:/^.{11}*b9ca5\K.{6}/
. El\K
operador descarta la coincidencia hasta ese punto, por lo que solo se devuelven los últimos seis caracteres.fuente
pink/purple
es#a6814c
, pero la respuesta correcta es#ef1de7
.Perl, 7,375 bytes
Almacena datos ligeramente comprimidos (
grey
->E
, etc.) como datos binarios comprimidos, los expande en un hash y devuelve la clave correspondiente después de reemplazar espacios en la entrada con_
. No creo que sea tan bueno, y estoy seguro de que otros tendrán métodos mucho más inteligentes para comprimir los datos, podría jugar con esto más adelante.Aquí está disponible un hexdump reversible que se generó usando este script .
Uso
fuente
Ruby,
1213112030 +-p
= 12033 bytesEl recuento de bytes es después de reemplazar
<compressed text>
con los datos de pasta sin procesar en http://pastebin.com/xQM6EF9Q . (Asegúrese de obtener los datos sin procesar debido a las pestañas dentro del archivo)Realmente podría reducir el texto aún más, pero he estado en ello durante unas horas y necesito dormir.
La entrada es una línea entubada de STDIN sin una nueva línea final. Agregar una nueva línea final requiere +3 bytes cambiando
($_+?\t)
a(chomp+?\t)
.fuente
BASH + bzip2,
805868096797 bytesAlmacena la lista original en un archivo después de comprimirla, no estoy seguro de si esto está permitido.
Llamar con:
fuente
dusty teal
, fallará. Lea todos los argumentos con$*
o algo así.bzgrep ..... c
en su lugarPython, 9360 caracteres
No usa ninguna biblioteca de compresión. Lo dejaré como un misterio por un momento cómo funciona y luego publicaré un enlace a la técnica. Por supuesto, podría acortarse almacenando los datos en formato binario, pero eso es un ejercicio para otro momento.
Explicación:
Utiliza una adaptación del código de http://stevehanov.ca/blog/index.php?id=119 para generar una búsqueda hash perfecta mínima de nombres de colores a códigos de colores.
fuente
Pitón 3, 4927
Código 182 + archivo de datos 4745
Teoría de operación:
md5((67*s).encode('ascii')).digest()[5:7]
es un hash perfecto de los nombres de color a un valor de 2 bytes. El archivo de datos binarios es simplemente una lista de fragmentos de 5 bytes: hash de 2 bytes y color de 3 bytes. El código codifica el nombre del color de entrada y busca entre los datos para encontrar una coincidencia.El código para generar el archivo binario:
Aquí está el código que usé para encontrar un hash perfecto. Nada especial, solo tres bucles anidados: cantidad de tiempo para repetir el nombre (por ejemplo, 'azul', 'azul azul', ...); los algoritmos hash disponibles; y las compensaciones en los hashes. Imprime combinaciones para las que no hay colisiones.
fuente
Python 3, 296 + 3960 = 4256 bytes
No lo usé
gperf
, porque sería demasiado aburrido simplemente repetir ese truco. En cambio, hice una solución de fuerza bruta desde cero y, por lo tanto, el tamaño no es óptimo (pero tampoco está mal).Sin embargo, descubrí cómo comprimir los colores de manera más eficiente: están ordenados y alineados a 4 bytes, LZMA se aprovecha de ello. (los colores se comprimen a 2180 bytes)
Para encontrar el color por nombre, se utiliza una función hash de 15 bits. Teóricamente podría encontrarse con menos bits (los números 0..949 pueden codificarse con 10 bits), pero mi computadora no pudo encontrar nada mejor, es demasiado trabajo.
El código toma la entrada de stdin e imprime la respuesta.
El código:
Archivo de datos (binario, debe nombrarse
a
y colocarse en la misma carpeta):Como correr:
fuente
C, 19,566 bytes
Un miserable 19,566 bytes.
Bog-standard C. El archivo rgb.txt se canaliza a través de stdin. El color a buscar se da como primer argumento.
Asi que:
./xkcd "bright sea green" < colors.txt
Da:
bright sea green -> #05ffa6
fuente
Java,
7,9787,435 bytesEl código es de 293 bytes, los datos son de 7.142 bytes
Golfizado:
Sin golf:
El archivo llamado "c" en el programa es el resultado de la operación inversa de este programa: tome el código hash de cada clave en el archivo de entrada y guárdelo con la representación entera del valor de color. Eso entra en una secuencia de salida de objeto, una secuencia de salida de GZip, luego una secuencia de salida de archivo. Este programa lo lee a través de los flujos de entrada inversa.
Los códigos hash predeterminados de Java de todos los colores son únicos en este conjunto de datos, por lo que es una buena clave de 32 bits en el mapa hash. El valor ya es un número entero, por lo que todo lo que debe hacerse es formatearlo correctamente como una cadena hexadecimal, rellenada con seis dígitos si es necesario, con una marca hash en el frente.
fuente
Java, 4649 bytes
Código Java: 497 bytes, archivo de datos: 4152 bytes
El archivo se puede encontrar aquí.
sin golf:
El programa usa una versión mejorada del código hash de Java que usa solo 17 bits:
Los colores se ordenan por componente azul creciente. Se almacenan en 18 bits: 8 para rojo, 8 para verde y 2 para azul delta.
Tamaño total del archivo: 949 colores * (18 + 17) = 33 215 = 4152 bytes
fuente
JavaScript (Node.js), 10785 bytes
Uso:
Datos codificados .
fuente
MATLAB, 94 + 7.243 = 7.337 bytes
Genere el archivo MAT "h.mat" con la variable "c" que contiene una lista ordenada de las sumas de verificación CRC32 de los nombres (c = java.util.zip.CRC32; c.update (uint8 (x)); c.getValue ();) y la misma lista ordenada de los códigos hexadecimales convertidos de los colores (sscanf (x (:, end), '% x')) como "e". Esto debería tener (R2013b, formato de archivo v7, un tamaño de 7.243 bytes.
La función es la siguiente
Aprovecha la compresión integrada de los archivos MAT y el soporte de java para la función CRC32.
fuente
Go, 6709 bytes
El código es de 404 bytes, los datos son de 6305 bytes
Los datos están codificados con
xxd -p
. Extraer en un archivo simplemente nombradof
conxxd -r paste f
. El código se puede ejecutar comogo run file.go "tree green"
fuente
C #, 6422 bytes
El código es 575 bytes, los datos son 5847 bytes
Los datos existen en un archivo GZipped adyacente que contiene una representación transformada de los datos originales. Las palabras de color que aparecen más de una vez se extraen y se colocan en una tabla de encabezado en la parte superior del archivo, precedidas por una longitud de un byte.
Las entradas de datos (después del encabezado) consisten en un conjunto de:
Cada entrada termina con 0xFF, 0xFE, 0xFD, lo que indica que los siguientes uno, dos o tres bytes siguientes representan el desplazamiento del valor de color, respectivamente.
La tabla se analiza en orden y el valor de color se acumula hasta que se encuentra una cadena coincidente con la entrada.
Código de descompresión / búsqueda minimizado:
Código de compresión de datos
fuente
C # 7,209 bytes: 6,643 bytes de datos + 566 bytes de código (878 bytes sin minimizar)
El repositorio de Github está aquí: https://github.com/nbcarey/color-map
Los nombres de colores se comprimen en el archivo de datos utilizando el hash FNV-32-1a ya que este algoritmo de hash está convenientemente libre de colisiones para este conjunto de nombres de colores. Por lo tanto, cada nombre de color se almacena como 4 bytes.
Cada color se almacena como 3 bytes (1 para rojo, verde y azul). No hay magia allí.
En consecuencia, cada asignación del nombre del color al valor RGV ocupa 7 bytes en el archivo comprimido.
Esta es una versión de una línea del hash FNV-32-1a (suponiendo una cadena que contiene solo caracteres ASCII simples:
Este archivo de datos comprimido está en el repositorio de github en https://github.com/nbcarey/color-map/blob/master/color-map/hashed-color-map.dat
Aquí está el código minimizado:
Y aquí está el código legible por humanos:
fuente
PHP, 5014 bytes
No es el mejor que hay, pero es tarde y necesito dormir un poco. :-)
La belleza de PHP es que puede insertar datos de carga útil en su script y leer el archivo en sí mismo, por lo que el script es autosuficiente. Simplemente descárguelo , ejecútelo y le solicitará el nombre del color.
El truco básico aquí es hacer hash de los nombres de colores y generar subcadenas de identificación mínima de ese hash. Descubrí que 4 caracteres de un hash SHA1 son suficientes, los primeros 3 y el 17 para identificar de forma única todos esos colores. La clave está en binario, así como en el código de color, que es convenientemente un byte por canal de color. Por lo tanto, cada entrada ocupa 5 bytes, lo que representa 5 x 949 = 4745 bytes de carga útil (el número mágico que ves en el código).
La compresión no ayudó mucho, bzip2, LZMA crearon archivos más grandes, así que sin más trucos, esto está tan comprimido como lo es para este enfoque.
fuente
Bash + (coreutils, gzip, xxd, openssl, sed, grep), 4946 bytes
datos: 4482 bytes, código: 464 bytes
Los datos se pueden encontrar en base64 aquí . Sé que el código puede ser más golfizado. Demasiado somnoliento ahora: / Cualquier sugerencia es bienvenida :-)
Explicación
Estas son las acciones que hice en el archivo original después de eliminar el comentario de licencia.
openssl dgst -md5 -binary|base64
base64
usa un conjunto de 64 caracteres para representar los datosA-Za-z0-9+/
,. Entonces, esperaba encontrar 2 bytes porque todas las entradas eran 494 y 64 * 64 = 4096 pero no pude encontrar ninguna. También intenté encontrar entradas únicas de 2 caracteres mediante elsha512
paso uno pero sin suerte. Entonces, me quedé con estos 3 bytes para los nombres de los colores.(echo '0:';echo -n "$line"|cut -d '#' -f 2)|xxd -rp -l 16|base64
zopfli -i1000
comprimir el archivo.Entonces el archivo de resultados antes de la compresión se vería así:
También probé otras utilidades de compresión pero con peores resultados, excepto
zopfli -i0000 --zlib
con 4470 bytes yzopfli -i10000 --defalte
con 4464, pero no estaba seguro de cómo descomprimir los formatos.Para encontrar el código de color, hago las acciones inversas. Creo el código de 3 caracteres a partir del nombre de pila y reconstruyo parcialmente los códigos de color originales. Por ejemplo, para
adobe
crear todo lo que comienza conX
:Luego agarro la
Xqy
línea y devuelvo la segunda parte, que es el hexágono de color.Realmente disfruté este rompecabezas y hay muchas respuestas geniales aquí. Gracias y buen trabajo a todos!
fuente
Bash + coreutils / xxd, 4064 bytes
Datos 3796 bytes (volcado hexadecimal del archivo de datos)
Bash 268 bytes
Sin golf
La idea general es escanear a través de campos de 32 bits, encontrar el hash de coincidencia único de 14 bits e imprimir el código de color en esa ubicación. La codificación de color de 18 bits aprovecha el enfoque de Super Chafouin.
El hash exclusivo de 14 bits comienza con un subconjunto de 14 bits del md5sum de 128 bits. Para encontrar esos bits, utilicé un algoritmo genético codificado en C ++ aquí . El código precarga un archivo fijo llamado "datos", que es solo el md5sum, uno por línea, en binario. Si lo necesita en forma de receta, esto creará el archivo de datos:
Encuentro el mejor candidato a 14 bits (que he visto hasta ahora) de este código en la generación 2, pero este conjunto tiene dos colisiones. Específicamente: mapa "barro" y "púrpura pálido" al mismo valor, y mapa "azul agua" y "verde claro" al mismo valor. Como solo hay dos colisiones y no he encontrado nada mejor, simplemente las desambigué; Resulta que la mitad de cada uno de estos valores de depósito no se utiliza.
Ya probé la compresión en d; pero ni bzip2, ni gzip, ni xz parecen reducir el tamaño de d.
fuente
Groovy,
153 + 10,697 = 10,850253 + 9870 = 10,123 bytesDecidí que quería una solución que involucrara solo un archivo, así que (al costo obvio del espacio) codifiqué una versión CSV GZIPped de los datos a caracteres Unicode 0x0020-0x007E (¿cuál supongo que sería una codificación base 95?). El código tiene 253 caracteres, el contenido de la cadena es de 10123 caracteres.
Para facilitar la lectura, esto es lo mismo con el texto codificado excluido:
Mi solución original era una codificación Base 64 más simple usando el codificador incorporado
Para facilitar la lectura, esto es lo mismo con el texto excluido:
fuente