O último desafio ( Pixel-art, episódio 1: exibir Super Mario ) foi apenas um treinamento ... (e você o completou de maneiras surpreendentes, obrigado!)
Desta vez, você tem que trabalhar um pouco mais. Você tem que exibir todo o primeiro mapa do mundo superior de Super Mario Bros no NES, sem inimigos e sem Mario.
Seu programa ou função deve exibir todos os pixels da imagem a seguir OU produzir um arquivo de imagem semelhante a ele (BMP, PNG ou GIF).
Seu programa não deve acessar a Internet de forma alguma.
A saída pode ser ampliada, se você desejar, e os pixels podem ser elementos ASCII ou HTML, se desejar, desde que tenham a cor certa.
Aqui está o modelo que você deve seguir:
A imagem inteira: http://i.stack.imgur.com/2kfVc.png
O conjunto de peças (se necessário): http://img.ctrlv.in/img/14/10/19/5443f44c7eb78.png
Você pode produzir seu próprio conjunto de peças, subconjunto ou superconjunto deste.
Você pode usar seu conjunto de peças como um arquivo de imagem separado ou incluí-lo em seu código (por exemplo, em base64). Se estiver separado, adicione seu tamanho em bytes à sua pontuação.O mapa com coordenadas: http://goo.gl/c8xJIx ou http://img.ctrlv.in/img/14/10/19/544373adc9f64.png
As cores:
Azul céu: # 5C94FC Preto: # 000000 Rosa: # FCBCB0 (para os blocos e o castelo) Marrom: # C84C0C (para os blocos e o castelo) Laranja: # FC9838 (para o bloco "?") Verde claro: # 80D010 (para arbustos, montanhas, mastro de bandeira, urdidura) Verde escuro: # 00A800 (para arbustos, montanhas, mastro de bandeira, urdidura) Branco: #FCFCFC (nuvens) Azul claro: # 3CBCFC (nuvens)
A resposta mais curta vence.
EDIT: Haverá dois quadros de pontuação, um em que as pontuações são contadas em bytes e outro em que são contadas em caracteres.
Boa sorte!
PS: Aqui estão algumas notas que podem ajudá-lo a otimizar seu programa:
- Nuvens, arbustos e montanhas têm um padrão repetitivo (a cada 48 colunas)
- Os blocos voadores estão presentes apenas nas linhas 4 e 8
- Cada bloco ou sprite do mapa usa no máximo 4 cores (incluindo azul ou transparente, dependendo de como você o vê)
- Os arbustos são apenas o "topo das nuvens" com uma paleta de cores diferente
- Arbustos / nuvens simples, duplos e triplos podem ser facilmente formados usando o mesmo mini-conjunto de peças de 16x16px. O mesmo vale para as montanhas simples e triplas
Respostas:
Código da máquina x86,
1729161914681382 bytesComo funciona: os blocos são gerados por uma combinação de compactação RLE, imagens de 2 bits e código processual. Depois que os blocos são gerados na memória, o programa cria uma matriz de índices de bloco. Isso é carregado primeiro com o plano de fundo repetido. Depois disso, os tubos, blocos flutuantes, pirâmides e o mastro da bandeira são desenhados proceduralmente. Os canos, colinas, arbustos e pirâmides podem se estender abaixo do solo, mas ficam encobertos quando os ladrilhos da rocha são escritos a seguir. Finalmente, os valores do bloco do castelo são simplesmente copiados para o local correto. Para gerar o arquivo de imagem, o cabeçalho e a paleta BMP são armazenados no arquivo como dados e são gravados primeiro. O programa é executado através da matriz, gravando a linha apropriada do bloco correspondente para cada posição.
Uso: Execute mario.com, ele gerará "m.bmp", um arquivo de imagem BMP padrão. O arquivo é criado como um arquivo oculto, pois acabou sendo menos bytes.
Faça o download de um arquivo ZIP contendo o código fonte e o binário, além da saída.
Código de montagem para gerar o arquivo executável:
fonte
Javascript compactado (*):
1285 1258 1253 1205 11861171 caracteres(*) Minificado usando Closure, RegPack e ObfuscaTweet, conforme sugerido por xem
A versão Unicode possui 4549 bytes de tamanho, sem ObfuscaTweet (somente Closure e Regpack), o tamanho é 2251 bytes.
História:
1285 -> 1258: variável
A
para 48 (thx @hsl), mesclou alguns dosfor
loops, mescloumt()
emu()
, usando índices de mosaico em vez de cadeias, otimizou png com PNGOUT1258 -> 1253: mesclou mais alguns
for
loops; renomeadomt()
parar()
; chaves desnecessárias removidas; variávelB
para 16; definir 16 sprites CSS não utilizados (substitui 32 porA
); mostrando 1 linha não utilizada (substitui 14 porB
); função removidae()
; encurtadot()
,g()
,c()
; usando emfor(i=0;i<n;)f(i++)
vez de semprefor(i=0;i<n;i++)f(i)
que possível1253 -> 1205: moveu o estilo do corpo para a parte CSS em vez de
<body style=...>
; substituiu algunsfor
loops porf
chamadas; funções optimizadasr
,q
;</head><body>
parece ser desnecessário<html><head>
também; funçãot(i)
para mapeamento CSS removido; Nomes CSSb0
.. emb31
vez dea
..z
,aa
..ff
1205 -> 1186: função
n
renomeada paraN
; nova funçãon
que opera em uma matriz com codificação delta1186 -> 1171: colinas e urdiduras podem ser desenhadas "grandes" a qualquer momento, as partes inferiores são desenhadas por blocos de pedra; use
d
para nuvens e arbustos; removeu alguns pontos e vírgulas desnecessáriosEsta é uma tentativa processual. Existem padrões em todos os lugares, um dos números mágicos é 48 (espaço entre nuvens, arbustos e montanhas). O conjunto de peças é codificado como string de URL de dados Base64 e usado como uma folha de estilo CSS. Em Javascript, a matriz 212x14
m
é preenchida com índices de bloco. Veja a versão desminificada comentada para mais detalhes.Funciona no Chrome 38 (Ctrl + T para a nova guia, Ctrl + Shift + J no console javascript, cole o código lá) e no Firefox 33 (se envolvido com tags javascript HTML). Também há uma versão do bin JS .
Ainda há espaço para otimizações, postarei atualizações e seria bom se algumas pessoas em JS / CSS / HTML sugerissem otimizações / correções.
Minificado:
Não minificado e comentado:
fonte
function l(i,j,s){for(k=0;k<j;k++)n(i+k*W,s);}
pode ser encurtado extraindo k ++ para a função, eu acho? O mesmo pode acontecer com a linha j.Python3
1638157616161513 bytesCódigo 581 + 932 dados
↑ Este topo é o nível original. No meio está o PPM gerado por esse script. Na parte inferior, há um diff, e isso mostra que a paleta e o mapa não concordam exatamente! Eu coloquei isso na falha de dados e não no meu script;)
(bytes contados sem comentários, sendo desempacotado por linha e recuando no segundo nível
\t
)Dados (codificados em base64 para serem colados; decodifique e salve como um arquivo chamado "i"):
O arquivo de dados é um formato personalizado que criei para esse problema e é armazenado como LZMA.
Primeiro, todos os 32 blocos são serializados. Existem 9 cores na paleta, e isso leva 8219 bytes descompactados. (Descobri que tentar comprimir os blocos a 4 bits por pixel não ajudou em nada a compressão. Não tentei forçar com força a melhor ordem dos blocos e provavelmente perdi alguns pontos aqui.)
Existem 212x14 = 2968 blocos que compõem o mapa.
As instruções para recriar o mapa agora estão codificadas.
Primeiro, vem uma seção de comandos "put" que coloca alguma sequência de blocos da paleta de blocos no mapa em um determinado x, y. Como existem 32 blocos, eu especifico uma execução do mesmo bloco usando um número maior que 32 em vez do índice do bloco.
Em seguida, vem uma seção dos comandos "copiar" que copiam algum retângulo do mapa atual para outro local. Há uma máscara de bits especial que marca se a cópia deve ser espelhada.
Um pequeno exemplo de buffer de comando:
(Eu disse resumidamente , mas na verdade é quase metade do buffer total de comando necessário para fazer todo o mapa; a grande maioria dos bytes nos dados são os 32 blocos de origem)
Em seguida, vem uma segunda seção dos comandos "put" e, finalmente, outra seção dos comandos "copy".
Como eles podem se substituir, eu posso criar partes de cópia que depois apago ou altero.
Posso sem dúvida barbear mais alguns bytes off-lo - por exemplo - transformando coloca em pequenas cópias e fazendo o
eval
truque em um código-fonte compactado, ou brincar com PNG (que é DEFLATE com filtros específicos de imagem) também. Mas eu gosto de coisas detalhadas como elas são.fonte
3,11
parece estar ausente na paleta. Parece haver algum ruído no mapa20,12
e o contorno geral de árvores e nuvens pode ser uma falha de alinhamento na paleta? Existem apenas 9 cores, portanto não pode haver nenhum tipo de artefato de mesclagem.Javascript,
106910721024 caracteres (1957 bytes)RegPacked e Obfuscatweeted
Código não ofuscado
Eu escondi esse código porque há um código não destruído abaixo.
Mostrar snippet de código
Código ungolfed
Primeiro criei blocos em sprites com o URI de dados compactados do @ schnaader.
0 ~ v
(que é 0 ~ 31 na base 31) representa cada bloco.E eu converti o mapa em blocos à mão. Esses dados possuem 212 caracteres por linha.
Depois substituí o caractere repetido (como
7
(céu) e1
(solo)) porrepeat()
.Encontrei
7
alguns blocos e outro7
padrão é repetido. Então eu criei outra função para torná-la compacta. Você pode vê-lo no código fonte não ofuscado.Finalmente eu RegPacked, e Obfuscatweeted meu código de golfe de 2341 bytes.
Foi um desafio muito engraçado. Obrigado! E obrigado ao @xem por mais truques.
fonte
JavaScript:
3620 (ouch)34293411Atualizações
Atualização nº 1:
var
definições removidas e coloque as declarações de variáveis entre colchetes do primeiro uso. RemovidogetElementById()
, pois também está disponível no carregamento como variável por ID. Usando emcloneNode()
vez decreateElement('CANVAS')
. Renomeado main dexMx
paraM
. Removido o recurso de dimensionamento :(, (ainda disponível no exemplo. )Adicionados alguns comentários ao código expandido. (Esse código não é atualizado com as remoções. A linha abaixo ("Mini código") é.)
Atualização # 2: Removida a função principal
M()
como um todo e deixou o código rodar na raiz . Isso exigiria que o código fosse colocado dentro de um invólucro de carga ou no final do documento.Atualização # 3: estatísticas adicionadas.
Mini código:
Blá blá:
- Demonstração no final da postagem.
Usando a tela como base para uma tentativa de resolver isso. Acabei com cerca de 6000 caracteres, mas depois de algumas brincadeiras (e uma compactação personalizada - com brincadeiras e ajustes também) agora estou no número indicado. Ainda alta, mas, novamente, a qualidade é boa ;-).
Ele também inclui uma opção de escala, primeiro argumento para a função
xMx()
, também conhecida como "principal" . 1 = tamanho normal (como em blocos de 16 bits). Não há muito espaço para ajustes; portanto, se usarmos frações, alguns dos ladrilhos não se encaixam melhor. Em números inteiros, deve estar OK.[1]Mas: aviso, subindo, consome recursos rapidamente e cria uma tela enorme. (Tudo é pintado de uma só vez.) Quando a largura original é de 3392 pixels, ela rapidamente se torna enorme. [1]
[1] A partir da atualização # 1, isso foi removido. Está presente na demonstração.
Estatísticas:
Main code : 870
Compression:
Main data : 2176 (17,480 bits)
Key : 128 ( 1,024 bits)
Code : 236
Whole she bang : 2540
Decompressed data : 5608 (44,864 bits)
Total : 3410
[1][1]: +1 byte, ";", entre o código principal / de dados.
Os dados compactados são uma matriz, Å e um "objeto" , Ø. Onde Å está segurando o posicionamento do ladrilho e o Ø mantém os dados para pintar os ladrilhos. O Ø deveria ter sido uma matriz também - mas como meu código começou com algo como isto:
Acabou como está. Talvez eu veja se não consigo consertar isso. O ideal seria torná-lo analisável com JSON em vez de eval (), mas isso não seria um ponto em um concurso como este. No momento, não é possível analisar o JSON devido a cotações ausentes nas partes de identificação.
Demo
Aqui está um violino onde é possível visualizar o código em ação. O código no violino eu expandi um pouco (e adicionei um pouco de estilo HTML / CSS ao redor do mundo - mas a imagem em si é autossustentada.):
MARIOS WORLD
Código expandido:
Código expandido e (um pouco) reorganizado:
fonte
var
para declarar variáveis; eles são declarados automaticamente quando você os define, portanto, você poderá removervar D,C,c,S,s,R,F,Z,
do seu código. (você também pode substituir/.{2}/
com/../
.)var
mas a deixei, pois precisava executar quando a publiquei. Feito agora. O RegExp foi legal, de alguma forma não conseguiu ver isso;)ev(a|i)l
rotina). Se for "legal" , clique em OK.eval(unescape(escape('𨑬𩑲𭀨𘣆𘠩').replace(/uD./g,'')))
funciona como pretendido. E sim, sua pontuação é contada em caracteres para que você possa usar totalmente truques como compactação e avaliação Unicode. Você pode ter uma pontuação perto de 1750 com isso!Python
133113261314127212681217 bytes(código:
219214202186182, dados:362 + 750 = 1112363 + 723 = 1086346 + 689 = 1035)A idéia aqui é que primeiro gere um mapa com um tamanho 16 vezes maior em cada dimensão, onde cada pixel é colorido pelo índice no mapa de blocos. Para garantir que a mesma paleta foi usada, primeiro combinei o mapa de blocos fornecido e o mapa em uma única imagem. A partir deste e do mapa de blocos (ambos os pngs minificados), agora podemos regenerar o mapa original. (O código para este processo pode ser visto abaixo do código de envio). Note-se que salvei o mapa de blocos como um arquivo "t" e o mapa gerado como uma imagem "m"
EDIT: Comecei a explorar como a ordem dos ladrilhos influenciava a compressão e, para fins de exploração, gerei 10000 permutações aleatórias e as comprimi com este resultado: tudo isso com os ladrilhos em uma linha, pois isso reduzia bastante o código pouco. Tentei coisas semelhantes com configurações diferentes (2 * 16, 4 * 8), mas nenhuma com um resultado médio melhor.
Supondo que o png fosse compactado melhor com regiões similares contínuas maiores, criei uma ferramenta que me permitia mover os blocos e, usando o que eu considerava uma imagem mais contínua, reduzi a imagem do bloco para 723, a partir de 750b.
EDIT2: Após muito mais análises sobre como o png realmente funciona, e muitas experiências (ainda em andamento), as imagens foram compactadas ainda mais. Link abaixo atualizado. Escreverei mais sobre essa análise mais tarde, quando estiver concluída.
Novas imagens usadas estão aqui: http://imgur.com/a/RgkXx
Aqui estão as outras imagens geradas no processo: http://imgur.com/a/HXTGA , embora algumas estejam um pouco desatualizadas devido à edição acima.
O script que escrevi para reduzir o mapa é bastante grosseiro, mas aqui vai (também pode estar desatualizado devido às alterações acima):
fonte
Perl 5 + PNG: 689 + 593 = 1282
Falha na tentativa de substituir o mapa de blocos compactados PNG da solução de Christian pelo código Perl. No final, são 65 bytes mais longos. Toma os mesmos blocos PNG na entrada e gera um PNG na saída.
Uso:
perl mario.pl <tiles.png >world.png
fonte
JS:
40123921 caracteresO JS é usado para descompactar muitos caracteres Unicode e escrever uma tag img cuja src é a imagem fornecida no OP, salva como PNG, compactada, codificada em base64 e aparada.
Demo: http://jsbin.com/fojidejoco/1/
PS: Eu sei que é um pouco trapaceiro (mesmo que as regras o permitam), mas pelo menos, isso nos dá um objetivo: fazê-lo em menos de 4012 caracteres.
Ferramentas usadas:
fonte