O formato PBM (Portable BitMap) é um formato de bitmap ASCII em preto e branco muito simples.
Aqui está um exemplo para a letra 'J' (copiada e colada no link da Wikipedia):
P1 # Este é um exemplo de bitmap da letra "J" 6 10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Está na hora de criarmos uma pequena ferramenta para gerar arquivos nesse pequeno e bacana formato!
Seu objetivo é escrever o programa mais curto (em qualquer idioma) que esteja em conformidade com as seguintes regras:
- Seu programa usa uma string de stdin (por exemplo
CODEGOLF.STACKEXCHANGE.COM!
) - Ele gera um arquivo PBM com uma representação de bitmap (legível) da sequência.
- Cada personagem é construído como uma grade 8x8.
- Você deve suportar os caracteres [AZ] (todos em maiúsculas), espaço, um ponto ('.') E um ponto de exclamação ('!').
- Nenhuma biblioteca externa permitida (certamente nenhuma relacionada ao PBM)!
- O conjunto de caracteres usado não deve ser simplesmente externo ao seu programa. Parte do desafio é armazenar os personagens com eficiência ...
O teste de validade do formato PBM pode ser feito com o GIMP (ou outros). Mostre a entrada e a saída da amostra!
A solução mais curta receberá os pontos de resposta em 31/01/2012.
Divirta-se jogando golfe!
PS: Eu adicionei uma recompensa (em porcentagem, uma grande parte da minha reputação de codegolf) para (espero) atrair mais concorrentes.
code-golf
string
graphical-output
ChristopheD
fonte
fonte
letters
outras palavras). Não muito diferente do exemplo vinculado a.Respostas:
GolfScript, 133 bytes
Isso se baseia na minha solução Perl de 164 bytes e usa a mesma fonte de 4 por 5 pixels cheia de petiscos. Mais uma vez, darei a versão legível primeiro:
Aqui,
FONT DATA HERE
significa 71 bytes de dados de fontes binárias compactadas. A codificação é um pouco diferente da versão Perl: em vez de dividir a sequência compactada no espaço em branco, eu a expanda primeiro e depois a divido na mordidela3
(escolhida porque acontece que não ocorre em nenhum lugar na fonte).Como os dados da fonte no script real contêm caracteres não imprimíveis, eu os dou como um hexadecimal abaixo. Use
xxd -r
para transformar o despejo hexadecimal de volta no código executável do GolfScript:Ao contrário do script Perl, este código imprime quaisquer caracteres fora do conjunto
A
-Z
,!
,.
,space
como rabiscos pequenos de aparência engraçada. Substituir os rabiscos por espaços em branco custaria 2 caracteres extras; removê-los inteiramente custaria 4.Este é o meu primeiro programa GolfScript, portanto, não ficaria surpreso se sobrar espaço para otimização. Veja como funciona:
{91,65>"!. "+?}%:s
mapeia os caracteres de entrada válidos (A
-Z
,!
,.
,space
) para os números 0 - 28 e atribui o resultado as
. Quaisquer caracteres fora do conjunto válido são mapeados para -1, que é o que produz os rabiscos quando impressos."P4"\,8*8
coloca os valores "P4", 8 vezes o comprimento da entrada e 8 na pilha. Quando impressos no final, eles formarão o cabeçalho PBM.{16base}%[3]/
pega a sequência anterior de dados da fonte, divide cada byte em duas mordidelas e divide o resultado em blocos delimitados pelo valor3
.{:p;{[p=0]0=}s%}%
depois faz um loop sobre esses blocos, primeiro atribuindo cada bloco à variávelp
e, em seguida, fazendo um loop sobre a sequência de entrada remapeadas
, substituindo cada caractere pelo valor no deslocamento correspondente emp
. A construção de aparência engraçada[p=0]0=
faz o mesmo quep=
, exceto que retorna 0 para quaisquer compensações após o final dep
; Eu realmente não gosto, mas não consegui descobrir uma maneira mais curta de lidar com isso.Finalmente,
]n*
pega tudo na pilha (os três valores do cabeçalho e a matriz de dados da imagem) e os une às novas linhas de impressão.fonte
Perl, 164 bytes, sem compactação zlib / gzip
Depois de dormir no problema, consegui descobrir uma solução muito mais curta que a minha primeira. O truque é tirar proveito de uma brecha menor nas regras: os personagens precisam caber em 8 por 8 pixels cada, mas nada diz que eles precisam preencher todo esse espaço. Então, desenhei minha própria fonte de 4 por 5 pixels, permitindo que eu agrupasse dois caracteres em 5 bytes.
A saída é assim:
(escalado x 4)
(tamanho original)
Antes de fornecer o código real com os dados da fonte incorporada, deixe-me mostrar uma versão descodificada:
No código real, ele
PACKED FONT DATA
é substituído por uma cadeia binária que consiste em oito linhas delimitadas por espaço em branco (quatro linhas de 14 bytes e uma de 13 bytes, mais três bytes nulos únicos para as linhas em branco). Projetei deliberadamente minha fonte para que os dados compactados não contenham espaços em branco, aspas simples ou barras invertidas, para que pudessem ser codificadosqw'...'
.Como a string da fonte compactada contém caracteres não imprimíveis, forneci o script real como um dump hexadecimal. Use
xxd -r
para transformá-lo novamente em código Perl executável:Veja como funciona:
A primeira linha (na versão de-golfed) lê uma única linha de entrada, divide-a em uma matriz de caracteres (convenientemente omitindo quaisquer mudanças de linha de arrasto) e mapeia as letras
A
aZ
e os caracteres!
e.
para os códigos de caracteres de 0 a 28, que normalmente correspondem a caracteres de controle não imprimíveis em ASCII / Unicode. (Um efeito colateral menor disso é que todas as guias na entrada são impressas comoJ
s.) O caractere de espaço é deixado sem mapeamento, pois o loop de saída transforma qualquer código acima de 28 em espaços em branco de qualquer maneira.A segunda linha apenas imprime o cabeçalho PBM. Ele usa o
say
recurso Perl 5.10 , portanto, você precisa executar esse scriptperl -M5.010
para que ele funcione.O loop de saída pega uma lista delimitada por espaços em branco de linhas de imagem compactada e atribui cada uma delas
$p
por vez. (Eu projetei a fonte para que os dados compactados não contivessem espaços em branco ou'
caracteres.) Em seguida, circula os caracteres de entrada@a
, usando ovec
comando Perl para extrair a mordidela de 4 bits correspondente ao código de caractere mapeado da linha da imagem, preenche-o em um byte de 8 bits e o imprime.Resposta antiga, 268 bytes:
Esta é uma primeira tentativa rápida e suja. Eu roubei a fonte do PleaseStand e a comprimi junto com o meu código-fonte. Como o script resultante é praticamente imprimível, aqui está um hexdump; use
xxd -r
para transformá-lo em código Perl executável:O código Perl descompactado consiste no seguinte preâmbulo:
seguido por oito repetições do seguinte código:
com
BITMAP DATA HERE
substituído com 29 bytes que codifica uma linha da fonte.fonte
Código da máquina 8086
190 bytes (122 bytes usando o BIOS)
Aqui está o arquivo .COM do WinXP / MSDos codificado em Base64:
(Use algo parecido com isto ) para decodificar o texto e salve como "pbm.com". Em seguida, no prompt de comando, digite:
Eu testei isso na minha máquina WinXP usando o prompt de comando padrão e o DosBox V0.74.
ATUALIZAR
Esta versão tem 190 bytes e usa a fonte minúscula de Ilmari Karonen (sem acesso ao BIOS aqui!): -
fonte
puts
em Ruby há uma biblioteca externa. Sim, ele usa as fontes da BIOS, acessadas por meio de uma referência de ponteiro (não háload
operação para colocar as fontes na RAM). Talvez inclinar as regras longe demais. Eu teria fugido com ele se não tivesse sido para aqueles miúdos traquinas ;-)Script de shell (código + dados = 295 caracteres)
Espero que tail, gzip e dd não sejam contados como "bibliotecas externas". Executar como
echo -n 'YOUR TEXT HERE' | ./text.sh > out.pbm
. A fonte que eu usei é Small Fonts tamanho 7.5, embora eu tenha que cortar o descendente do Q.Saída de exemplo
Código (137 caracteres)
Script completo
(use
xxd -r
para recriar o arquivo original)Explicação
od
é o programa utilitário padrão "octal dump". A-tu1
opção diz para produzir um despejo decimal de bytes individuais (uma solução suficiente para a falta de asc (), ord (), .charCodeAt () etc. do bash).P4
é o número mágico de um arquivo PBM de formato binário, que comporta oito pixels em cada byte (em comparaçãoP1
com o arquivo PBM de formato ASCII). Você verá como isso se mostra útil.dd
. (tail -2 $0
extrai as duas últimas linhas do script; os dados compactados incluem um byte de alimentação de linha 0x0a.) Acontece que oito pixels têm a largura de um único caractere. Os bytes nulos que preenchem as lacunas entre os caracteres suportados são facilmente compactáveis porque são todos iguais.wc -c
imprimindo o nome do arquivo de entrada "8" após a contagem de bytes.fonte
Python 2,
248247 bytesUsa uma fonte 3x5, compactada em uma sequência imprimível, 3 bytes por caractere. A fonte é claramente legível, embora n esteja em minúsculas ev possa ser confundido com au se não for visto no contexto.
Tamanho atual:
Zoom 3 x:
A saída é um PBM do tipo P1, conforme o exemplo no desafio. Foi um desafio divertido.
fonte
Ruby 1.9, 346 bytes (código 122 + dados de 224 bytes)
Aqui está o resultado:
(É bom, não é?)
A fonte foi gerada por
figlet -f banner -w 1000 $LETTERS
e este script .Corra com
echo -n 'CODEGOLF.STACKEXCHANGE.COM!' | ruby script.rb > image.pbm
.O script gera todas as linhas e simplesmente as imprime.
Aqui está um hexdump (use
xxd -r
):São necessários 93 bytes de código ao usar o goruby:
O uso do ZLib reduz o tamanho dos dados para 142 bytes em vez de 224, mas adiciona 43 bytes no código, portanto 307 bytes:
O que dá um total de 268 ao usar o goruby:
fonte
Java
862826:Aqui está uma abordagem diferente. Eu acho que 'awt' não conta como lib externa.
E não destruído:
Robô é a maneira mais curiosa de Java chamar getPixel. Eu crio um Label com o alfabeto e meço onde está um pixel para cada letra.
No método de pintura,
int py = (y < 3) ? y : y +1;
e(8*a+x+17+x/4, py+81)
é a maneira mais complicada, de ajustar a posição na fonte. Huuuh! caso contrário, seria necessário 9 linhas e, a cada 4 letras, há um pixel adicional na horizontal. Tentativa e erro me levaram a esta solução.Em seguida, o cabeçalho do PBM é gravado e cada linha da mensagem. A mensagem é passada como título do quadro.
É isso aí. Não é o código mais curto, mas não é necessário pintar a fonte manualmente.
Talvez possa ser mais curto no BeanShell ou Scala.
E agora - como é?
Vários zooms aplicados:
Unzoomed:
Não que o número de caracteres seja o número de caracteres da solução Perl embaralhados.
(jogou um pouco mais. Tornou o robô estático, o que evita uma declaração de exceção.)
fonte
eog
(Eye of Gnome) e uma captura de tela. Carregarei umajpg
versão sem escala ; talvez o seu navegador use uma interpolação de vizinhos mais próxima :).C ++ muito grande para ganhar
Eu escrevi um programa de desenho PPM completo em C ++, com minha própria fonte de bitmap. Mesmo eliminando todas as funções não necessárias, ainda é enorme comparado às respostas aqui por causa da definição da fonte.
De qualquer forma, aqui está a saída para HELLO WORLD:
E o código:
ppmdraw.h
ppmdraw.cpp
main.cpp
Makefile
Se você estiver interessado, a biblioteca completa do PPMDraw está aqui :
fonte
SmileBASIC, 231 bytes
Cada caractere contém apenas 2 padrões de linha diferentes, escolhidos de uma "paleta" de 8 combinações. Os dados para cada símbolo são armazenados em 1 byte, com a paleta armazenada separadamente.
fonte