O desafio do golfe é codificar e compactar a imagem a seguir dentro de um arquivo de origem.
Para fazer isso você precisa escrever 3 funções: red
, green
e blue
que aceitem x / y coordenadas da imagem e voltar a G / valor correspondente R / B pixels entre 0-255.
Aqui está o código de teste C / C ++:
#include <stdio.h>
#include "your_file"
int main() {
int x, y;
for(y = 0; y < 32; ++y)
for(x = 0; x < 32; ++x)
printf("%i %i %i\n", red(x, y), blue(x, y), green(x, y));
}
E a saída: http://pastebin.com/A770ckxL (você pode usar isso para gerar seus dados de imagem)
Regras e detalhes:
- Isto é um golf
- Apenas o seu código / arquivo é jogado no golfe - o código de teste é separado
- O conjunto de caracteres usado é ASCII, no entanto, caracteres de controle em cadeias só podem ser usados se forem escapados (como '\ n' e '\ r' etc.)
- Tudo deve estar contido na fonte - sem carregamento de arquivo
- Sua saída deve corresponder à saída de exemplo. Isso significa compactação sem perdas.
Línguas:
O problema foi escrito com o C / C ++ em mente, mas estou removendo essas restrições. Com isso dito, ainda vou recomendar usá-los.
Respostas:
C,
796 754 712 703 692 685 682 670 666 662 656648 caracteresChangelog:
return
ao#define
, substituindoif
por?
instruções (obrigado @FUZxxl), removendoint
da lista de parâmetros de funções.#define
p[]
eh[]
, mais algumas?:
melhoriasb
,i
não é mais necessário.m=b
em vez dem=11
e emn<2e3
vez dei<356
- estes são quase um comportamento indefinido / corrupção de memória, mas parece que tenho sorte :)k
agora é (32,16,8,4,2,1,0) em vez de (5,4,3,2,1,0). Gotcha, DC;)p[]
eh[]
, convertidoh[]
em umchar*
- awwww, há um gatinho sonolento nele^<+_=>-
while
=>for
,l=l*2+...
=>l+=l+...
m=m>9?...
=>c[n++]=m>9?...
b[]
, para que possamos mapear para 64-127 em vez de 0-63 e não precisarmos mais de índice de bitsk
. Obrigado @Piotr Tarsa . Substituído?:
(extensão GCC) por||
. Obrigado @JamesBp[]
)A imagem é convertida em uma sequência do tipo Base64 (ASCII 37-100), usando a codificação huffman para codificar as cores de 0 a 9 usando 3-6 bits e uma cor especial 10 (o pixel é igual ao anterior) usando apenas 1 bit.
Foram copiadas duas coisas da resposta do bunnit,
#define
e toda a imagem sendo decodificada completamente toda vezred
/green
/blue
são chamadas. Há espaço para melhorias adicionais, portanto, espere algumas atualizações :) Não tenho certeza sobre a conformidade do código, usei o GCC 4.6.1 para compilar e testar.Em termos de compressão, acho que a codificação aritmética ajudaria, pois a distribuição é bastante distorcida, mas talvez a sobrecarga do código seja muito pesada nesse caso. O LZW também deve fazer um trabalho muito bom. As cores são bastante locais, portanto, a codificação adaptativa pode ser uma ideia.
Versão mais legível de 754 caracteres com alguns comentários:
fonte
int
das listas de parâmetros para remover mais alguns bytes.m=m>9?c[n-1]:m;
paraif(m>9)m=c[n-1];
?if(k<0){j=b[i++]-37;k=5;}
que nãok>=0?:(j=b[i++]-37,k=5);
? (Este código utiliza uma extensão de C gcc,x=a?:b
é o mesmo quex=a?a:b
, com a diferença de que uma é avaliada apenas uma vez.red(x,y){while(i<356){--k>=0?:(j=b[i++]-37,k=5);l*=2;if(j&(1<<k))l++;for(m=0;m<11;m++)l!=h[m]?:(m=m<=9?:c[n-1],c[n++]=m,l=0,m=12);}return P;}
Python (
684.592caracteres)Como esse desafio está agora aberto a todos, por que não! É a rota de codificação familiar zlib -> base64, então peço desculpas por isso. Esperemos que uma entrada com alguma aparência de criatividade seja mais curta!
Aqui está um trecho de teste análogo ao original:
fonte
C ++, 631 caracteres; C - 613
Um codificador mtf unificado base-92, C ++, 631 caracteres:
E a versão C acima (613 caracteres):
Apenas para incluir uma entrada com dados da base 95 e codificação aritmética + modelo estatístico adaptável.
o código do schnaader usa ~ 438 caracteres para dados e o meu apenas 318 (311 sem mascarar).
Mas, como esperado, a codificação aritmética é muito complicada para uma amostra pequena como essa.
(Este é 844 caracteres)
Testes (da versão base-96 anterior):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC
De alguma forma SO come códigos 7F, então eu tive que atualizá-lo para base = 95
fonte
C ++ -
15251004964 caracteresCriou uma matriz z que armazena todas as cores possíveis como um único número inteiro (r << 16 | g << 8 | b). Criou uma matriz d que armazena {quantidade, valor}, o valor é a posição na matriz z, a quantidade é o número de pixels consecutivos com esse valor (ou seja, 3,0, significa colout t [0] aparece nos próximos 3 A matriz real de pixels (c) é calculada toda vez que o vermelho é chamado.O valor na matriz é então deslocado para a direita e ANDed conforme necessário para obter o componente correto.
Provavelmente eu poderia salvar mais alguns caracteres (~ 50) retirando mais padrões da matriz, conforme definido.Editar 1 - alterou a matriz d para uma matriz de caracteres com cada valor compensado por 48, o que significa que eu posso representá-la como uma sequência que economiza uma carga de vírgulas.
Editar 2 - Tirou uma parte maior das funções da instrução define.
fonte
int
(o queint f(int x,int y)
se tornaf(x,y)
.)Javascript,
696694 caracteresAgradecimentos a schnaader por 696 -> 694.
Imaginei um formato de codificação diferente, que é essencialmente a codificação de execução com uma tabela de pesquisa de cores. Funciona bastante bem, porque há menos de 16 cores e elas aparecem menos que 16 vezes seguidas; portanto, cada definição de pixel, incluindo o comprimento, cabe em um byte. Coloquei a cor na parte alta do byte e a contagem na parte baixa.
No final, a string base64 acabou sendo mais longa do que eu esperava (472 caracteres), mas o programa de decodificação é realmente curto.
Nota: Dividi o código para ter um pouco de legibilidade. Ele precisa estar em uma linha para executar.
Código do teste:
Eu acho que o resultado do exemplo é realmente a saída de vermelho, verde, azul (não vermelho, azul, verde, como no código de teste original); funciona para mim assim mesmo.
fonte
[0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]
- isso salva 1 caractere e é da ordem GBR em vez de RGB.C ++, 1357 caracteres
Desobstruído um pouco:
C
contém os valores RGB para as dez cores distintas da imagem.E
contém os dados da imagem, onde cada elementoE[i]
codifica uma contagem de repetiçãoE[i]/10
e um índice de coresE[i]%10
.fonte
int red(x,y){R Q(x+32*y)[0]}(only
definições em funções sem nomes de tipo como # define`return
), poderá ser capaz de se barbear com mais caracteres.Python 3 (589 caracteres)
Código de teste
Baseado na solução da Dillon Cower
fonte
PHP (5.4) - 822
Fiz isso deliberadamente sem usar nenhuma das funções de compactação internas . Esta solução não está concluída, não tenho certeza se desisti, posso ver áreas para melhoria, mas não encontro tempo / força de vontade para refatorar tudo no momento, por isso estou postando o que tem até agora.
Novas linhas + comentários a serem removidos por 822 bytes.
Esboço de teste:
A compactação dos dados da imagem em si é bastante boa, mas as funções para recuperar valores RGB ocupam 1/4 do código.
Estou usando um mecanismo de codificação base70 + personalizado.
Os dados da imagem codificada referenciam o índice da matriz de um RLE, que por sua vez indexa a matriz de cores. Não tenho certeza de quanto isso sobrecarga adiciona ou subtrai diretamente sobre as cores.
Seno existem 10 cores (0 a 9), os RLEs são armazenados como
run_length * 10 + colour_index
. Fornecendo uma variedade de codificações entre 10 e 145 sem experimentar otimizações baseadas na ordem das cores. (ou seja, eu poderia fazer o intervalo de 19 a 140 movendo as cores de 0 a 5, 5 a 9 e 9 a 0 - mas isso pode ter outros efeitos indiretos)Uma resposta anterior afirma que seus dados codificados são 472 bytes. Meus dados de imagem codificados são 352 bytes, mas o RLE intermediário / mapa de cores (que não é codificado em binário) tem mais 129 bytes, colocando o total em 481. (além de sobrecarga adicional para unir os dois). No entanto, suspeito que meu método possa ser melhor dimensionado para imagens maiores.
FAÇAM:
global
é uma droga, mas não pode acessar índices de caracteres em constantes.fonte
C (gcc) , 602 bytes
Experimente online!
Atropelar
fonte