Randall Munroe (autor do XKCD) realizou uma pesquisa para dar nomes às cores . O principal resultado é uma lista de nomes para as 954 cores mais comuns de monitores RGB .
Para facilitar a programação, aqui está a lista em texto simples: http://xkcd.com/color/rgb.txt . Cuidado, a primeira linha não é de dados, mas contém a licença.
Escreva um programa ou função que use um nome de cor válido da lista acima como entrada e produz o código de cor RGB associado. Seu programa não precisa manipular entradas inválidas de nenhuma maneira definida.
Aplicam-se brechas padrão. Além disso, sua resposta não deve usar códigos de cores predefinidos (embutidos ou externos) <-> mapas de nomes de cores. (Isso inclui a lista vinculada.) O código mais curto em bytes vence. Se você ler um arquivo, a contagem de bytes do arquivo deverá ser incluída.
Exemplos:
dark peach -> #de7e5d
robin's egg blue -> #98eff9
pink/purple -> #ef1de7
shit #7f5f00
-bubble gum pink #ff69af
,bubblegum pink #fe83cc
Respostas:
Perl 5 -
421239563930407 bytes para o código e 3523 para o arquivo de dados. Os dados binários são lidos no arquivo 'g', cujo hexdump pode ser encontrado aqui .
Isso usa uma função hash perfeita gerada usando o GNU gperf , que atribui cada nome de cor a um número inteiro exclusivo no intervalo de 0 a 6304 que pode ser usado para indexar uma tabela. Os dados compactados em gz contêm os valores de cor no formato de 1 byte, indicando o deslocamento na tabela da cor anterior e, em seguida, 3 bytes para a própria cor (com dois dígitos hexadecimais por byte). (Um byte de 0 para o deslocamento significa que na verdade é o próximo valor + 255, pois nem todos os ajustes cabem em um byte).
O código analisa os dados para criar a tabela que contém a sequência de cores rgb e aplica a função hash (convertida em perl) à entrada para selecionar a saída correspondente da tabela.
Uso:
Editar: reduziu ainda mais o tamanho, compactando com gzip o arquivo de dados
fonte
EXCEL, 18 (+ 18269)
Apenas para definir uma linha de base, mostrarei a solução mais simples do Excel que consegui pensar:
Código
O código no Excel é muito simples:
A entrada deve ser colocada entre aspas duplas.
Dados
Os dados devem ser armazenados em um arquivo .csv, parecido com o seguinte:
Quando clico no CSV, ele abre automaticamente o Excel e coloca os dados nas colunas A e B, pode ser necessário um separador diferente.
fonte
Ruby,
5.37988 + 9 + 5.220 = 5.317 bytes+9 bytes para
-rdigest
sinalizador.... mais um dicionário de 5.220 bytes como dados binários lidos em STDIN (ou argumento do nome do arquivo). Você encontrará o dicionário no formato xxd no snippet abaixo. O programa usa um nome de cor como argumento, então você o invoca assim:
Se alguém puder descobrir uma maneira mais curta de como ler um arquivo e usar um nome de cor como argumento, deixe um comentário.
$*
(ARGV) e$<
(ARGF) interagem de maneiras estranhas e ocultas, portanto$*.pop
.Dicionário (formato xxd)
Mostrar snippet de código
Explicação
Codificando o dicionário
A construção do dicionário é muito simples. Pego o hash hexadecimal MD5 do nome da cor e concatenar o segundo ao sexto dígitos hexadecimais (que são exclusivos para cada cor) com o código de cores de seis dígitos. Uno-os a uma única sequência de 10.439 dígitos hexadecimais. Depois, converto isso nos 5.219,5 bytes equivalentes, preenchidos com zeros à direita por até 5.220 bytes.
O engraçado: tentei compactar o dicionário e até
zopfli -i100
produzi um arquivo 40 bytes maior . Apenas por diversão, calculei a entropia do dicionário binário e é 99,8% (contra, por exemplo,rgb.txt
61,2%). Não é ruim!Aqui está o código que gera o dicionário:
Decodificando e pesquisando no dicionário
Este é exatamente o oposto do acima. Primeiro, eu converto os dados binários em sua representação hexadecimal de 10.439 dígitos. Então pego a sequência de entrada (nome da cor) e obtenho o segundo ao sexto dígito hexadecimal de seu hash MD5 e uso uma expressão regular para encontrar esses dígitos na sequência hexadecimal de 10.439 dígitos em algum índice divisível por 11 e retornando os 6 dígitos subsequentes , que são o código de cor correspondente. Por exemplo, para o hash
b9ca5
( "azul turva"), a seguinte expressão regular é construída:/^.{11}*b9ca5\K.{6}/
. O\K
operador descarta a correspondência até esse ponto; portanto, apenas os últimos seis caracteres são retornados.fonte
pink/purple
é#a6814c
, mas a resposta correta é#ef1de7
.Perl, 7.375 bytes
Armazena dados levemente compactados (
grey
->E
, etc) como dados binários compactados, expande-os para um hash e retorna a chave correspondente depois de substituir espaços na entrada por_
. Não acho que seja tão bom e tenho certeza de que outros terão métodos muito mais inteligentes para compactar os dados. Talvez eu possa brincar com isso mais tarde.Um hexdump reversível está disponível aqui, que foi gerado usando este script .
Uso
fonte
Ruby,
1213112030 +-p
= 12033 bytesA contagem de bytes é após a substituição
<compressed text>
pelos dados brutos da pasta em http://pastebin.com/xQM6EF9Q . (Certifique-se de obter os dados brutos por causa das guias no arquivo)Eu realmente poderia diminuir ainda mais o texto, mas já estou nisso há algumas horas e preciso dormir.
A entrada é uma linha canalizada do STDIN sem uma nova linha à direita. A adição de uma nova linha à direita requer +3 bytes, alterando
($_+?\t)
para(chomp+?\t)
.fonte
BASH + bzip2,
805868096797 bytesArmazenou a lista original em um arquivo após compactá-lo, não tendo certeza se isso é permitido.
Ligue para:
fonte
dusty teal
, falhará. Leia todos os argumentos com$*
ou algo parecido.bzgrep ..... c
vez dissoPython, 9360 caracteres
Não usa nenhuma biblioteca de compactação. Vou deixar isso como um mistério por um tempo, como funciona e depois postar um link para a técnica. É claro que isso poderia ser reduzido, armazenando os dados em um formato binário, mas isso é um exercício para outra hora.
Explicação:
Usa uma adaptação do código em http://stevehanov.ca/blog/index.php?id=119 para gerar uma pesquisa de hash perfeita mínima dos nomes das cores para os códigos de cores.
fonte
Python 3, 4927
Código 182 + arquivo de dados 4745
Teoria de Operação:
md5((67*s).encode('ascii')).digest()[5:7]
é um hash perfeito dos nomes das cores para um valor de 2 bytes. O arquivo de dados binários é simplesmente uma lista de blocos de 5 bytes - hash de 2 bytes e cor de 3 bytes. O código faz o hash do nome da cor de entrada e pesquisa os dados para encontrar uma correspondência.O código para gerar o arquivo binário:
Aqui está o código que eu usei para encontrar um hash perfeito. Nada sofisticado, apenas três loops aninhados: número de vezes para repetir o nome (por exemplo, 'azul', 'blueblue', ...); os algoritmos de hash disponíveis; e as compensações nos hashes. Ele imprime combinações para as quais não há colisões.
fonte
Python 3, 296 + 3960 = 4256 bytes
Eu não usei
gperf
, porque seria muito chato simplesmente repetir esse truque. Em vez disso, fiz uma solução de força bruta do zero e, portanto, o tamanho não é o ideal (mas também não é muito ruim).No entanto, descobri como compactar cores com mais eficiência - elas são classificadas e alinhadas em 4 bytes; o LZMA aproveita-se disso. (as cores são compactadas para 2180 bytes)
Para encontrar a cor pelo nome, é usada uma função de hash de 15 bits. Teoricamente, ele poderia ser encontrado com menos bits (os números 0..949 podem ser codificados com 10 bits), mas meu computador não conseguiu encontrar nada melhor, é muito trabalho.
O código recebe a entrada do stdin e imprime a resposta.
O código:
Arquivo de dados (binário, deve ser nomeado
a
e colocado na mesma pasta):Como executar:
fonte
C, 19.566 bytes
Uns miseráveis 19.566 bytes.
Padrão Bog. C. O arquivo rgb.txt é canalizado através do stdin. A cor a encontrar é dada como o primeiro argumento.
Tão:
./xkcd "bright sea green" < colors.txt
Dá:
bright sea green -> #05ffa6
fonte
Java,
7.9787.435 bytesO código tem 293 bytes, os dados são 7.142 bytes
Golfe:
Ungolfed:
O arquivo chamado "c" no programa é o resultado da operação inversa deste programa: pegue o código hash de cada chave no arquivo de entrada e armazene-o com a representação inteira do valor da cor. Isso entra no fluxo de saída do objeto, no fluxo de saída GZip e no fluxo de saída do arquivo. Este programa lê através dos fluxos de entrada inversos.
Os códigos de hash Java padrão de todas as cores são exclusivos nesse conjunto de dados, portanto, é uma boa chave de 32 bits no mapa de hash. O valor já é um número inteiro; portanto, tudo o que precisa ser feito é formatá-lo corretamente como uma sequência hexadecimal, preenchida com seis dígitos, se necessário, com uma marca de hash na frente.
fonte
Java, 4649 bytes
Código Java: 497 bytes, arquivo de dados: 4152 bytes
O arquivo pode ser encontrado aqui
ungolfed:
O programa usa uma versão aprimorada do hashcode Java que usa apenas 17 bits:
As cores são classificadas pelo componente azul aumentando. Eles são armazenados em 18 bits: 8 para vermelho, 8 para verde e 2 para azul delta.
Tamanho total do arquivo: 949 cores * (18 + 17) = 33215 = 4152 bytes
fonte
JavaScript (Node.js), 10785 bytes
Uso:
Dados codificados .
fonte
MATLAB, 94 + 7,243 = 7,337 bytes
Gere o arquivo MAT "h.mat" com a variável "c" que contém uma lista classificada das somas de verificação CRC32 dos nomes (c = java.util.zip.CRC32; c.update (uint8 (x)); c.getValue ();) e a mesma lista classificada dos códigos hexadecimais convertidos das cores (sscanf (x (:, end), '% x')) como "e". Isso deve ter (R2013b, formato de arquivo v7, um tamanho de 7.243 bytes.
A função é a seguinte
Ele aproveita a compactação interna dos arquivos MAT e o suporte a java para a função CRC32.
fonte
Go, 6709 bytes
O código é 404 bytes, os dados são 6305 bytes
Os dados são codificados com
xxd -p
. Extraia para um arquivo simplesmente nomeadof
comxxd -r paste f
. O código pode ser executado comogo run file.go "tree green"
fonte
C #, 6422 bytes
O código tem 575 bytes, os dados são 5847 bytes
Os dados existem em um arquivo GZipped adjacente que contém uma representação transformada dos dados originais. As palavras coloridas que aparecem mais de uma vez são extraídas e colocadas em uma tabela de cabeçalho na parte superior do arquivo, prefixada com um comprimento de um byte.
As entradas de dados (após o cabeçalho) consistem em um conjunto de:
Cada entrada é finalizada com 0xFF, 0xFE, 0xFD, o que indica que o próximo, dois ou três bytes a seguir representam o deslocamento do valor da cor, respectivamente.
A tabela é analisada em ordem e o valor da cor é acumulado até que uma string correspondente à entrada seja encontrada.
Código de descompressão / pesquisa minimizado:
Código de compactação de dados
fonte
C # 7.209 bytes: dados de 6.643 bytes + código de 566 bytes (878 bytes não minimizados)
O repositório do Github está aqui: https://github.com/nbcarey/color-map
Os nomes de cores são compactados no arquivo de dados usando o hash FNV-32-1a, pois esse algoritmo de hash é conventientemente livre de colisões para esse conjunto de nomes de cores. Portanto, cada nome de cor é armazenado como 4 bytes.
Cada cor é armazenada como 3 bytes (1 para vermelho, verde e azul). Não há mágica lá.
Conseqüentemente, cada mapeamento do nome da cor para o valor RGV ocupa 7 bytes no arquivo compactado.
Esta é uma versão de uma linha do hash FNV-32-1a (assumindo uma cadeia contendo apenas caracteres ASCII simples:
Esse arquivo de dados compactados está no repositório do github em https://github.com/nbcarey/color-map/blob/master/color-map/hashed-color-map.dat
Aqui está o código minimizado:
E aqui está o código legível por humanos:
fonte
PHP, 5014 bytes
Não é o melhor que existe, mas é tarde e eu preciso dormir um pouco. :-)
A vantagem do PHP é que você pode incorporar dados de carga útil em seu script e ler o próprio arquivo, para que o script seja auto-suficiente. Basta fazer o download , executá-lo e ele solicitará o nome da cor.
O truque básico aqui é o hash dos nomes das cores e gerar minimamente substrings de identificação desse hash. Descobri que 4 caracteres de um hash SHA1 são suficientes, os primeiros 3 e 17 para identificar exclusivamente todas essas cores. A chave está no código binário e no código de cores, que é convenientemente um byte por canal de cores. Portanto, cada entrada ocupa 5 bytes, o que representa 5 x 949 = 4745 bytes de carga útil (o número mágico que você vê no código).
A compactação não ajudou muito, o bzip2, o LZMA criou arquivos maiores, portanto, sem mais truques, isso é o mais compactado possível para essa abordagem.
fonte
Bash + (coreutils, gzip, xxd, openssl, sed, grep), 4946 bytes
dados: 4482 bytes, código: 464 bytes
Os dados podem ser encontrados em base64 aqui . Eu sei que o código pode ser mais jogado. Com muito sono agora: / Todas as sugestões são bem-vindas :-)
Explicação
Aqui estão as ações que fiz no arquivo original após remover o comentário da licença.
openssl dgst -md5 -binary|base64
base64
usa um conjunto de 64 caracteres para representar os dadosA-Za-z0-9+/
,. Então, eu esperava encontrar 2 bytes, porque todas as entradas eram 494 e 64 * 64 = 4096, mas não encontrei nenhuma. Também tentei encontrar entradas exclusivas de 2 caracteres usando asha512
etapa um, mas sem sorte. Então, fiquei com esses 3 bytes para os nomes das cores.(echo '0:';echo -n "$line"|cut -d '#' -f 2)|xxd -rp -l 16|base64
zopfli -i1000
comprimir o arquivo.Portanto, o arquivo de resultado antes da compactação ficaria assim:
Tentei outros utilitários de compactação também, mas com piores resultados, exceto
zopfli -i0000 --zlib
com 4470 bytes ezopfli -i10000 --defalte
com 4464, mas não sabia como descompactar os formatos.Para encontrar o código de cores, faço as ações inversas. Eu crio o código de 3 caracteres a partir do nome fornecido e reconstruo parcialmente os códigos de cores originais. Por exemplo, para
adobe
criar tudo o que começa comX
:Então eu cumprimento a
Xqy
linha e retorno a segunda parte, que é a cor hexadecimal.Eu realmente gostei deste quebra-cabeça e há muitas ótimas respostas aqui. Obrigado e bom trabalho a todos!
fonte
Bash + coreutils / xxd, 4064 bytes
Dados 3796 bytes (despejo hexadecimal de arquivo de dados)
Bash 268 bytes
Ungolfed
A idéia geral é digitalizar campos de 32 bits, encontrar o hash de 14 bits exclusivo correspondente e imprimir o código de cores nesse local. A codificação em cores de 18 bits aproveita a abordagem de Super Chafouin.
O hash exclusivo de 14 bits começa com um subconjunto de 14 bits do md5sum de 128 bits. Para encontrar esses bits, usei um algoritmo genético codificado em C ++ aqui . O código pré-carrega um arquivo fixo chamado "data", que é apenas o md5sum, um por linha, em binário. Se você precisar disso na forma de receita, isso criará o arquivo de dados:
Eu acho o melhor candidato 14 bits (que eu vi até agora) desse código na geração 2, mas esse conjunto tem duas colisões. Especificamente: mapa "lama" e "roxo pálido" com o mesmo valor e mapa "azul marinho" e "verde claro" com o mesmo valor. Como existem apenas duas colisões e não encontrei nada melhor, apenas as desambiguo; Acontece que metade de cada um desses valores de bucket não é usada.
Eu já tentei compactação em d; mas nem bzip2, nem gzip, nem xz parecem diminuir o tamanho de d.
fonte
Groovy,
153 + 10.697 = 10.850253 +9870 = 10.123bytesDecidi que queria uma solução que envolvesse apenas um arquivo, então (com o custo óbvio de espaço) codifiquei uma versão CSV dos dados em GZIP para caracteres Unicode 0x0020-0x007E (que eu acho que seria uma codificação base 95?). O código tem 253 caracteres, o conteúdo da String tem 10123 caracteres.
Para facilitar a leitura, eis o mesmo com o texto codificado excluído:
Minha solução original era uma codificação Base 64 mais simples usando o codificador embutido
Para facilitar a leitura, eis o mesmo com o texto excluído:
fonte