Depois de passar um tempo no Stack Exchange, posso reconhecer a maioria dos sites nas Perguntas sobre a rede quente pelo seu pequeno ícone (que também é o seu favicon ), mas certamente nem todos eles. Vamos escrever um programa que pode! Você deve escrever um código que determina o site, considerando um dos 132 favoritos (atualmente), incluindo o Stack Overflow em japonês (que ainda está na versão beta privada):
Fiz upload de um arquivo ZIP com todas essas imagens como PNGs no GitHub . Clique no botão "Raw" para fazer o download. A ordem dos ícones acima é a ordem alfabética dos nomes dos arquivos no zip.
Os nomes de sites correspondentes (nesta ordem) são:
Notas:
- Eu removi o
®
deLEGO® Answers
eExpressionEngine® Answers
, assim você não precisa se preocupar com Unicode. - Eu usei nomes em inglês para o Stack Overflows em japonês e português pelo mesmo motivo.
- Os ícones da ciência da terra e da língua espanhola são indistinguíveis. Portanto, dado um desses ícones, seu código pode retornar um desses sites (de sua escolha). O mesmo vale para Magento e Artes Marciais .
Regras
Você pode escrever um programa ou função que
- recebe o nome do arquivo (local) da imagem via STDIN, argumento da linha de comando ou argumento da função ou recebe o conteúdo do arquivo de imagem via STDIN
- retorna ou imprime em STDOUT o nome do site, conforme listado acima.
Seu código deve reconhecer todos os 132 sites corretamente (com a exceção mencionada acima).
Você não pode fazer nenhuma suposição sobre o nome do arquivo (assim chamado codegolf.png
). Você pode supor que a imagem tenha dimensões 16x16 e que será realmente uma das 132 imagens acima. As imagens acima são todas PNG, mas você pode usar qualquer outro formato gráfico de varredura conveniente, mas precisará converter as imagens por conta própria. Você não deve fazer suposições sobre o fluxo de bytes real do arquivo de imagem, exceto que é uma imagem válida em qualquer formato que você escolher. Em particular, se houver várias maneiras de codificar a mesma imagem em seu formato (por exemplo, adicionando campos irrelevantes à seção do cabeçalho), seu código deverá funcionar para todos eles. Em resumo, seu código deve confiar apenas nos valores de pixel, sem detalhes do arquivo que o codifica.
Como de costume, você não pode buscar dados da Internet. Você precisa determinar o site apenas a partir da imagem.
Você pode usar funções internas ou de terceiros para ler o arquivo de imagem e obter uma lista de valores de cores, mas não deve usar outras funções de processamento de imagem existentes.
Isso é código de golfe, então a resposta mais curta (em bytes) vence.
fonte
pngcrush
não existirão.Respostas:
Travesseiro Python 3.x +,
230118941878 bytesA idéia é fazer a hash da imagem e encontrar a string correspondente de um dicionário (assim como outras respostas).
O código da chave é este:
Abrimos o arquivo e o convertemos em uma sequência de 1024 bytes de valores RGBA. Com um pouco de experimentação, descobrimos que a soma de verificação ADLER-32 de cada sexto byte dessa cadeia de bytes é exclusiva para essas 132 imagens. E, em seguida, testes adicionais mostram que, tendo o módulo de 2003 da soma de verificação, é o menor dicionário.
O dicionário original se parece com:
Percebemos que todos os nomes de sites não contêm números. Portanto, podemos concatenar o dicionário inteiro em uma única string:
E então use o regex, por exemplo,
1969(\D+)
para extrair o nome do site. Essa sequência enorme é compactada para economizar espaço (deixe o mecanismo de compactação perceber as múltiplas ocorrências de "Idioma") e, finalmente, codificado na base 85.Como agora também está marcado como complexidade kolmogorov , aqui uma solução de 2394 bytes que não usa compactação (o zlib ainda é importado para o adler32).
fonte
.tobytes()
obtém os dados de pixel (16 × 16 × 4 = 1024), por isso depende da imagem. O arquivo precisa estar em RGBA.C #, 2760 bytes
Minha solução não usa hash, na verdade examina os pixels individuais da imagem e decide com base nisso. Descobri que bastava examinar o componente azul da imagem módulo 9. A idéia é dividir repetidamente com base no valor do pixel.B% 9, assim:
Usando um script, gerei o seguinte programa monstruoso (5197 bytes) que resolve o problema usando uma árvore de decisão binária:
Algumas pessoas usaram funções de compactação incorporadas em suas soluções. Fiz o meu próprio, escrevendo um script que identifica substrings comuns e os substitui por atalhos de caracteres simples. O código é compactado para a seguinte sequência de 2502 bytes:
O dicionário necessário para descompactação é de apenas 108 bytes:
O dicionário usa ponto e vírgula como delimitador e contém caracteres únicos seguidos por sua descompressão. Para descompactar, ":" seria substituído primeiro por "&", depois "<" por "%!", "|" por "ic" e assim por diante. A descompressão de uma string c pode ser expressa de uma maneira bastante concisa:
Depois da descompressão, uso um pouco de magia negra de reflexão para compilar o código rapidamente e executá-lo:
Observe que os exemplos usados aqui para explicação são ligeiramente diferentes dos usados na solução de 2876 bytes.
fonte
Node.js,
3178313026672608 bytesCalcula o hash SHA1 dos dados de imagem de cada arquivo e, usando os bytes 16 a 19 do resumo hexadecimal, indexa os nomes dos sites.
Usando os bytes 12 a 16 do resumo hexadecimal do hash SHA1 de cada arquivo, indexa os nomes dos sites. Pode haver uma combinação mais curta usando apenas 3 bytes do resumo hexadecimal.fonte
h="17352368".match(/.{4}/g)
(os hashes de 4 caracteres, divididos em uma matriz),s="MathOverflow;StackOverflow in Portuguese".split(";")
(nomes separados por um;) e, em seguida, monte tudo novamente:t={}h.forEach(function(k,i){t[k]=s[i]})
(resulta no mesmo objeto que o seu código). Existem 132 pontos e vírgulas; portanto, mesmo se você alternar para um caractere de 2 bytes (o OP diz que não deve haver unicode nos nomes dos sites), você economizará espaço. Além disso, você pode adicionar a otimização do @manatwork além dessa economia adicional.split()
: us uma única sequência como "1234Site; 5678Other". Então, supondo que não haverá choque entre fragmentos hash e nomes de sites, uma únicamatch()
irá fazê-lo:function $(e){r=require;return"8d4fAcademia;3a6dAndroid Enthusiasts;5caeAnime & Manga;804cAsk Different;bef3Arduino".match(r("crypto").createHash("sha1").update(r("fs").readFileSync(e)).digest("hex").slice(12,16)+"([^;]+)")[1]}
Python 2.7,
19061889 bytesEsta solução usa o CRC32 nos dados de pixel para criar um identificador exclusivo da base 95 de 2 dígitos. O índice do identificador é então usado para procurar a sequência de respostas.
A parte complicada foi encontrar uma combinação de funções no estilo hash que resultaria em 132 (ou 131) rótulos pequenos mas exclusivos. Eu tentei algumas opções antes de escolher esta. Parece bastante compacto.
O programa usa Python PIL para ler os dados de pixel do arquivo.
Python 2.7 2150 bytes
Esta é uma versão sem usar bibliotecas de compactação ou codificação. A Lista de Trocas de Pilha é compactada com um método de troca simples. Os caracteres que não são usados no texto:
são usados para armazenar segmentos de string comuns. O texto não é compactado com a
for k,v in [(v[0],v[1:]) for v in K.split('|')]:T=T.replace(k,v)
linha. A tabela de indexação de dois caracteres é a mesma do programa acima.fonte
C #, 2672 bytes
A tabela (sequência) de rótulos e hashes SHA parciais é compactada para salvar alguns bytes. O dicionário original se parece com:
fonte
var
deve proteger alguns bytes. 2) O que há com o construtor de cordas? Não o vejo usado. 3)StreamReader.ReadToEnd
pode ajudar um pouco também.