Introdução
O Atari ST era um computador pessoal bastante popular entre meados dos anos 80 e início dos anos 90, alimentado por um microprocessador Motorola 68000. Nesta máquina, o comportamento padrão do sistema operacional para exceções de CPU não capturadas era exibir uma linha de bombas na tela, conforme mostrado na figura a seguir:
Fonte: https://commons.wikimedia.org/wiki/File:Row_of_bombs.png
Nota: Dependendo da versão do sistema operacional, os gráficos da bomba podem variar um pouco. Mas vamos tomar este como referência.
O número de bombas depende do vetor de exceção, sendo as mais comuns:
- ($ 008) Erro de barramento: 2 bombas
- ($ 00c) Erro de endereço: 3 bombas
- ($ 010) Instrução ilegal: 4 bombas
Objetivo
Seu objetivo é escrever um programa ou função que imprima ou produza uma arte ASCII dessas bombas Atari ST.
Entrada
Um número inteiro que representa o número de bombas a serem exibidas. Seu código deve suportar os valores mais comuns: 2, 3 e 4. Suportar menos e / ou mais bombas é bom, mas não é necessário nem está sujeito a um bônus.
Resultado
A bomba original consiste em um bloco de 16x16 pixels, representado aqui em ASCII e binário:
....##.......... 0000110000000000
.#.#..#......... 0101001000000000
.......#........ 0000000100000000
#..#....#....... 1001000010000000
..#...#####..... 0010001111100000
......#####..... 0000001111100000
....#########... 0000111111111000
...###########.. 0001111111111100
...###########.. 0001111111111100
..#############. 0011111111111110
..########.####. 0011111111011110
...#######.###.. 0001111111011100
...######.####.. 0001111110111100
....#########... 0000111111111000
.....#######.... 0000011111110000
.......###...... 0000000111000000
Nesse desafio, cada bomba ASCII deve ser esticada até o dobro da largura original para obter uma melhor renderização. Portanto, ele consistirá em 16 linhas de 32 caracteres, usando ##
pixels 'ON' e dois espaços para pixels 'OFF'. Todas as peças da bomba devem ser colocadas lado a lado. Espaços principais são proibidos. Espaços de fuga também são proibidos, exceto aqueles que realmente fazem parte do bloco de bombas (ou seja, as 31ª e 32ª colunas) que devem estar presentes. Você pode incluir não mais que uma quebra de linha inicial e não mais que uma quebra de linha final.
Exemplo
Abaixo está a saída de referência para duas bombas, em que as quebras de linha obrigatórias são marcadas como \n
e as quebras de linha extras toleradas são marcadas como (\n)
:
(\n)
#### #### \n
## ## ## ## ## ## \n
## ## \n
## ## ## ## ## ## \n
## ########## ## ########## \n
########## ########## \n
################## ################## \n
###################### ###################### \n
###################### ###################### \n
########################## ########################## \n
################ ######## ################ ######## \n
############## ###### ############## ###### \n
############ ######## ############ ######## \n
################## ################## \n
############## ############## \n
###### ###### (\n)
(Obviamente, outros formatos de quebra de linha, como \r
ou também \r\n
podem ser usados.)
Regras
Isso é código-golfe, então a resposta mais curta em bytes vence. As brechas padrão são proibidas.
fonte
Respostas:
Geléia ,
4344 bytes+1 byte - esqueceu de dobrar os caracteres (não que alguém tenha notado!)
TryItOnline
Quão?
A preparação foi compactar os dados como uma codificação de execução da imagem original:
1
s (espaço) ou0
s (hash) na imagem, ignorando novas linhas - produz uma lista[4,2,11,1,1,...]
:;[0,15]
;v
,, com o índicei
ao contrário e some16**i*v
=19468823747267181273462257760938030726282593096816512166437
);[5,119,249,42,...]
:;¥vẏ)X;ndĊɓ¡ẹ3ċi}Ịɲ¡P
Agora, o código avalia esse número, mapeia
1
s e0
s para caracteres de espaço e hash *, dobra cada um, divide-se em linhas e repete cada um o número apropriado de vezes.* na verdade, a implementação é realizada no módulo 2 para salvar bytes, portanto os espaços são ímpares e os hashes são pares:
fonte
05AB1E ,
57555350 bytesUsa a codificação CP-1252 .
Experimente online!
Explicação
Como a imagem de saída consiste apenas de 2 caracteres, podemos representá-la como um número binário.
Podemos ignorar novas linhas, pois todas as linhas têm o mesmo comprimento.
Podemos ignorar o último caractere de cada linha, da mesma forma para todas as linhas.
Usamos a imagem mais fina, pois ocupa menos espaço e podemos duplicar facilmente cada caractere posteriormente.
Usando 1 para representar espaço e 0 para representar # , obtemos o número binário:
111100111111111101011011111111111111101111111011011110111111110111000001111111111000001111111100000000011111000000000001111000000000001110000000000000110000000010000111000000010001111000000100001111100000000011111110000000111111111100011111
Em seguida, convertemos isso em base 10 e depois o compactamos na base 214, a base máxima em 05AB1E. O resultado disso é:
A carne do programa consiste no seguinte:
fonte
Pitão,
575654535150 bytesO código contém caracteres não imprimíveis, então aqui está um
xxd
hexdump reversível .Experimente online.
fonte
JavaScript (ES6),
159154140136 bytesEconomizou muitos bytes graças a @Hedi e @Arnauld
São 104 caracteres, mas (infelizmente) 136 bytes UTF-8. A sequência foi gerada com este trecho:
Mostrar snippet de código
Usar em
.replace
vez de[...string].map
é igualmente longo:Como funciona
Como cada linha dos dados brutos pode ser representada como um número de 16 bits, podemos armazenar o arquivo inteiro em uma sequência de 16 caracteres. O algoritmo de compactação pega cada linha binária, a inverte e a inverte (uma vez que toda linha no original termina em 0 , toda linha na versão modificada agora começa com 1 ), depois a transforma em char e concatena os caracteres resultantes .
Para descompactá-lo, precisamos extrair o código e transformar sua representação binária em uma cadeia de hashes e espaços. Isso pode ser feito com uma função recursiva, da seguinte maneira:
f
pega repetidamente o último bit deq
, selecionando dois espaços se for 1 ou dois hashes se for 0 e concatena isso com o resultado da execuçãof
no restante deq
. Isso é executadox.charCodeAt()
, transformando o código de caractere na sequência correta de espaços e hashes.(Havia muito mais drama aqui antes, mas a técnica de economia de 4 bytes apagou tudo isso.)
Depois disso, podemos apenas repetir os
n
tempos das strings e adicionar uma nova linha. Este é o método mais curto de descompressão que encontrei, mas fique à vontade para sugerir métodos possivelmente mais curtos.Outras tentativas de compactar a sequência:
O primeiro deles tem 153 bytes, portanto, nenhum deles chega perto de 136 ...
fonte
+x?'##':' '
vez de" #"[x].repeat(2)
x.charCodeAt()
vez de convertê-los em binários? (Acho que pouparia cerca de 8 bytes.)Arquivo .com do MS-DOS, 84 bytes
ESTÁ BEM. Só por diversão, porque não consigo vencer os 50 bytes ...
Tentei no DOSbox e no MS-DOS 6.22 em uma máquina virtual.
No DOSbox, o programa funciona bem; no entanto, no MS-DOS real, a saída não será exibida corretamente porque o DOS requer CR-LF em vez de LF no final da linha.
(No entanto, a saída está correta.)
Uma variante de 88 bytes usaria CR-LF no final da linha.
Aqui está o arquivo:
O código do assembler (na sintaxe da AT&T) fica assim:
--- Editar ---
Esqueci de mencionar: O programa deve ser iniciado com a seguinte linha de comando:
Nome do arquivo COM + exatamente um caractere de espaço + Número de bombas (1-9)
fonte
objdump -dw
A saída é uma boa maneira de mostrar o binário bruto, desde que você veja quais bytes são quais instruções. Eu fiz isso para as respostas gcd e adler32 . (Bem como incluindo o código fonte comentou que as pessoas tentem se.)Python,
223179 bytesSegunda abordagem:
Experimente em repl.it!
Em vez de criar uma lista de strings on-the-fly, há uma string hexadecimal codificada que é indexada e convertida em binária; então cada dígito binário é transformado em um
' '
ou'#'
, que é duplicado e unido ... etc.Primeira abordagem:
Experimente em repl.it!
Ele contém uma lista codificada das seqüências de caracteres de cada linha (sem incluir espaços à direita) criadas duplicando uma
' '
ou'##'
várias vezes. Para cada uma dessas cadeias de caracteres, elas são preenchidas com espaços até 32 caracteres, duplicadosn
vezes e, em seguida, unidas a novas linhas.fonte
'\n'
. Entãolambda n:print(*(''.join(2*' #'[int(d)]for d in bin(int('0c0052000100908023e003e00ff81ffc1ffc3ffe3fde1fdc1fbc0ff807f001c0'[i:i+4],16))[2:].zfill(16))*n for i in range(0,64,4)))
,. Além disso, você não precisa contar os bytes necessários para atribuir um nome ao lambda. Então, sua pontuação pode ser 176.C,
250240208188 bytesMude para o uso de uma função.
Teste assim.
main(c,v)char**v; { f(atoi(v[1])); }
fonte
0x
./// ,
539532 + n. de bytes de bombasA primeira /// resposta, exibindo 4 bombas. Os quatro primeiros 1s podem ser substituídos por qualquer representação unária do número de bombas que você deseja imprimir (11 para 2, 111 para 3)
Experimente online!
Se a entrada precisar ser decimal, o seguinte possui
555548 bytes (onde o último dígito pode ser alterado para 1, 2, 3 ou 4):Experimente online!
As partes mais importantes do código são as seguintes:
| significa //
ABCDEFGHIJKLMNOP significa cada linha da bomba, respectivamente
S significa 2 espaços
s significa 4 espaços
* significa 6 espaços
q significa 8 espaços
T significa ## (2)
t significa #### (4)
^ significa ##### # (6)
r significa ######## (8)
e significa ################ (16)
A maior parte do código é garantir que as bombas sejam impressas lado a lado, não um em cima do outro.
fonte
CJam , 66 bytes
Experimente online! (observe que existem alguns caracteres não imprimíveis no código.)
A bomba é codificada como um número no binário usando 1 para espaços (o espaço inicial como 1 garante que não tenhamos que preencher as representações binárias), transposta e depois convertida em string na base-136 (que produziu a string mais curta sem caracteres largos). Estes passos podem ser executados aqui .
Essa resposta inverte a codificação, o principal truque é repetir a bomba antes da transposição, concatenando efetivamente cada linha da bomba de uma só vez. Os caracteres em cada linha podem ser dobrados com novas linhas inseridas para a saída final.
fonte
PHP,
138104 + 32 = 136 bytesEu nunca pensei que isso
file
fosse binário seguro. Eu só gostaria de ter encontrado uma maneira mais interessante de armazenar os dados; mas nada que eu tentei vencer binário bruto.0
por 2 espaços,1
por##
,repetir
$argv[1]
tempos, imprimir resultado + nova linhacorrer com
-r
dados binários no arquivo
b
:código para gerar o arquivo:
fonte
\n
.MATL ,
6463605958 bytesExperimente online!
Explicação
O código usa uma versão pré-compactada da matriz binária 16 × 16. A pré-compactação (que não faz parte do programa) usou duas etapas:
A cadeia compactada,
é descompactado da base 94 para a base 16:
O vetor obtido dos tempos de execução mais 1 é multiplicado por 2:
para realizar o alongamento horizontal.
O vetor de comprimento de execução contém 49 valores. Os números originais a serem repetidos com esses comprimentos devem ser
[0 1 0 1 ... 0]
(49 entradas). Mas, em vez disso, é mais curto usar o vetor[1 2 ... 49]
, que será igualmente válido graças à indexação modular. Portanto, a decodificação de execução éO vector gerado containis as corridas de
1
,2
, ...49
, para um total de 512 entradas. Isso é remodelado em uma matriz 16 × 32:e usado como índices modulares na cadeia
' #'
para produzir uma única bomba:Finalmente, a repetição horizontal por um fator fornecido pela entrada produz o resultado desejado:
fonte
Python 2: 143 bytes
Está no ideone
(Eu percebi que a codificação direta da bomba original na base 36 fazia com que o código fosse mais curto em Python.)
A string foi formada tratando espaços como 1s e hashes como 0s e depois convertendo para a base 36. O programa então converte novamente em binário e fatias em comprimentos de 16 (com um deslocamento de 2 para o '0b' na frente do Python. string binária), converte em espaços duplos e hashes duplos, junta-os, repete os
n
tempos da string e imprime.Anterior: Python 2,
169 166163 bytesEstá no ideone
Quase um porto da minha resposta Jelly .
fonte
Python 2.7,
144141 bytesA bomba é escrita em binário com 1 para espaço, o primeiro 1 elimina a necessidade de preencher representações binárias. A bomba é transposta (como na minha resposta CJam ) e armazenada na base 36.
O programa decodifica a bomba para binária e itera bits em uma etapa de 16 efetivamente após a transposição (que economiza bytes ao cortar uma determinada linha). A linha resultante é concatenada, os bits são substituídos por duplicado
ou
#
e unidos em uma cadeia de caracteres simples.fonte
O
por alguma razão ...C (gcc) ,
216 204 183 183134 134 bytesExperimente online!
Escrito como um programa independente (
201 183151 bytes)Experimente online!
Isso ocorre se um parâmetro da linha de comandos não for fornecido.
fonte
Lote, 415 bytes
Nota: a linha
set s=
termina em 5 espaços. Aceita a contagem como um parâmetro de linha de comando. Simplesmente percorre cada linha da bomba (compactada levemente removendo séries de 5 caracteres idênticos) e repete a bomba quantas vezes desejar antes de finalmente duplicar cada caractere.fonte
Python 2,
206205203199191188186184160 bytesOlhou para Hex a lista de números, mas não pareceu economizar o suficiente para fazer valer a pena o esforço. Esperava poder aplicar o código, mas parece ter chegado o mais longe possível com essa abordagem. Quaisquer dicas adicionais recebidas com gratidão.
EDITAR
-1 alterando
e==1
parae>0
. Eu sempre esqueço esse.-2 ignorando o comprimento da cadeia binária, acrescentando 7 0 e obtendo apenas os últimos 16 elementos. Funciona como nunca há mais de 7 0s principais.
-4 porque agora que perdi a segunda referência à variável b, posso usá-la
bin(y)[2:]
diretamente na função map, levando-a abaixo da mágica 200 :-)-8 usando a atribuição de fatia na segunda lista. Aprendi algo novo esta noite.
-3 com agradecimentos a @ Jonathan
-2 usando em
c=d=([0]*7+map(int,bin(y)[2:]))[-16:]
vez de terc=d;
-2 novamente graças a @Jonathan
-24 com agradecimentos a @Linus
Resultado
fonte
" #"[e>0]*2
vai funcionar(...)
podem ir (RE: por meu comentário anterior).for y in ...:print"".join(" #"[e>0]*2for e in(([0]*7+map(int,bin(y)[2:]))[-16:]))*z
RProgN ,
210193 bytesSalvei alguns bytes alternando 0 = '' 1 = '##' para 1 = '' 0 = '', isso significa que não preciso adicionar os zeros extras de volta. Além disso, isso significa que agora a string B64 que costumava dizer "MAFIA" não, isso é triste.
Explicação
Bastante longo, a expansão, a impressão e a sequência compactada são 105 dos bytes. Pode ser um pouco mais jogável, mas pelo menos funciona.
A entrada está implicitamente na pilha, a pilha é implicitamente impressa.
Resultado
Tente!
fonte
PHP,
144140139138136 bytesNota: usa codificação Windows-1252
Execute assim:
Ou usando a codificação IBM-850 (135 bytes e resultado mais bonito):
Explicação
Isso não faz nada binário e não requer um arquivo externo.
Cada número de 16 bits é revertido e, em seguida, codificado como um número de base 36, preenchido com um avanço,
0
se necessário, portanto, a cada 16 bits resulta em 3 bytes. Concatenando esses resultados em01c02203k07d1j81j46b4cmwcmwpa4ohobugc8o6b434w0ow
. O código inverte o processo para que as bombas sejam impressas corretamente naN
hora.Tweaks
$j
para zero nos limites da linha com%=
. Isso se livra dos parênteses$argn
fonte
GCC C 129 bytes
ISO8859 / ASCII
Em uma linha:
Correr com:
Compile a origem como ISO8859-x (ASCII).
NB óÿÿþÿoÜüðààÀ! ÀCàCðøþ? deve conter os códigos ASCII invisíveis, mas foi quebrado devido à maneira como o StackExchange apresenta seu conteúdo. Consulte o link ideaone para obter a codificação de teste adequada. Alternativamente, a string ASCII original está em: https://github.com/claydonkey/AtariBombs/blob/master/ISO8859_REPR2.txt
Explicação
Primeiro, uma conversão da representação hexadecimal de bombas [f3 ff ad ff fe ff 6f 7f dc 1f fc 1f f0 07 e0 03 e0 03 c0 01 c0 21 c0 43 e0 43 f0 07 f8 0f fe 3f] para UTF-8 (no Na versão UTF-8, o compilador armazena a sequência como Wide Char Array - 2 ou 4 bytes para cada caractere em tempo de execução, mas isso é acadêmico). Enquanto os caracteres UTF-8 seriam armazenados como 2-4 bytes, esses valores estão todos dentro da ISO-8859-1 (ASCII) e, portanto, requerem apenas 1 byte. Também é seguro ser armazenado como ISO-8859-x (não há valores 0x8_ ou 0x9_). Portanto, o texto consome 32 bytes na ISO-8859 e a rotina consome 135 bytes no total.
(Caracteres de largura NB são armazenados como um número inteiro de 16 bits no Windows e 32 bits no Linux, mas novamente isso é irrelevante para a tarefa em questão)
Advertência: Nem todos os caracteres são exibidos (os caracteres de controle abaixo de 0x20). Eles ainda estão presentes. A maioria das páginas da web é utf-8 / 8859/1253 ( https://w3techs.com/technologies/overview/character_encoding/all ), então acho que isso é legítimo
(mudar todos os valores abaixo de 0x20 para ASCII imprimível deve corrigir isso).UTF-8
Aqui está a versão mais próxima da postagem original com fonte codificada em UTF-8. Isso consome 173 bytes. A string em si é de 50 bytes da fonte. A rotina também é mais longa, já que os bytes ASCII agora são armazenados com zeros de preenchimento para os Wide Chars de 16 bits / 32 bits e precisam ser alterados em vez de convertidos para uint16_t como acima. Eu mantive isso, pois pode ser verificado com ideona que usa codificação UTF-8.
Correr com:
Se você pode definir o valor implícito como um número inteiro de 16 bits no complier, pode omitir a declaração do tipo wchar_t do Wide Char. Ideone não reclama, então eu acho que é bom ir.
Experimente em ideone
fonte
Haskell, 155 bytes
Como uma função com o tipo
Int -> String
:Imprimir diretamente no IO custará 5 bytes (ou 6, se preferirmos retornar em
IO ()
vez deIO [()]
):fonte
C, 175 bytes
concatena cada x para si próprio e faz p exceder o limite para terminar cada linha.
fonte
Java, 228 bytes
fonte
n->{String s="";for(int x,r=0;r<16*n;s+=(++r%n<1?"\n":""))for(x=16;x-->0;)s+=((new int[]{1536,10496,128,18496,4592,496,2044,4094,4094,8191,8175,4078,4062,2044,1016,224}[r/n])&(1<<x))<1?" ":"##";return s;}
( 205 bytes ) Além de usar um Java 8 lambda, reduzi mais bytes alterando: a posição dox=16
(e altereiwhile
parafor
); 2x==0
a<1
; retornando ems
vez de imprimi-lo (as importações também fazem parte da contagem de bytes).--x>=0
parax-->0
. Ainda assim, ótima resposta, então +1!J, 89 bytes
Codifica a string como um número base-95, incrementa cada dígito por e
32
, em seguida, representa-a por uma string ascii.Explicação
Isso é composto de duas partes principais. Há a construção da bomba e a repetição real. Por enquanto, vamos nos referir à bomba como
b
. Em seguida, o código se parece com:Quando chamado com entrada
k
, isso é equivalente a:b
é uma bomba in a box, entãok#b
fazk
repetiçõesb
,;
achata verticalmente e|:
transpõe o resultado. (Ab
própria bomba é construída transposta.)Agora, aqui está a bomba:
A sequência a seguir é uma sequência codificada na base 95 com um deslocamento de
32
, para que todos os caracteres caiam no intervalo ASCII e, felizmente, não há'
s que precisem ser escapados.3 u:
obtém os códigos de caracteres da string,32x-~
torna cada número umx
número desejado e subtrai32
dele;95#.
converte em um número base-95 e2#.inv
converte-o em uma matriz de dígitos binários. Eu adicionei um líder1
ao binário para torná-lo um número sólido, então eu o tiro com ele}.
. Eu moldo a matriz em uma tabela 16x1616 16$
e a transponho usando|:
. (Possível golfe para mais tarde: transponha a string literal codificada.)2#
Duplica cada caractere na largura. Ficamos com uma tabela de0
s e1
s.' #'{~
mapeia0
s para' '
e1
para'#'
. Assim, ficamos com nossa bomba.Caso de teste
fonte
Bacon ,
229227195 bytesUma contribuição no BASIC por uma questão de nostalgia. A variável 'a' determina a quantidade de bombas.
Saída :
fonte
Haskell,
191181 bytesfonte
C (Atari TOS 2.06 US),
129 124 117113 113 bytesIsso usa o bitmap de bomba da ROM do TOS, que é um pouco diferente do da pergunta. Para outras versões do TOS, será necessário ajustar o endereço indicado por
*a
. Observe que algumas ROMs de emulador não incluem o bitmap da bomba!Se você não fornecer um argumento de linha de comando, várias bombas de bitmap mapeadas de alta resolução podem ser exibidas :-)
fonte
C ++ 11, 252 bytes
fonte
SmileBASIC, 127 bytes
(Captura de tela da versão sem caracteres duplicados) O
SB possui uma fonte quadrada, portanto, a duplicação dos caracteres parece ruim (e não cabe na tela)
Os caracteres não ASCII foram substituídos por
x
's.Valores hexadecimais:
0008,0002,0610,1F8A,3FC1,7FC1,7FF2,FFF4,FFF8,EFF0,73F0,7FC0,3FC0,1F80,0600
como o SB salva arquivos em UTF-8, alguns deles contam como 2 ou 3 bytes.
fonte
FOR K=1TO N
comINPUT N
, eu acho que exibe o número de bombas fornecidas na entrada. No entanto, devo dizer que, apesar da fonte quadrada, acredito que os caracteres ainda devem ser dobrados para manter a consistência com os requisitos (para evitar uma vantagem sobre outras respostas). Você pode manter a atual para obter uma solução mais agradável, mas acho que você ainda deve adicionar uma solução correta. Depois de adicionar isso, votarei pelo uso criativo dos caracteres UTF-8!Ruby 2.x (lambda) - 157 bytes
Provavelmente pode ser jogado ainda mais, mas eu gosto desta versão:
Idéia semelhante à da (s) versão (ões) do python: divida a sequência de bombas codificadas hexadecimais em seções de 4 caracteres, converta em binário, traduza
1
para#
e0
para, dobre cada caractere e imprima a matriz resultante.
Observe que o put é usado para imprimir a matriz. Isso imprimirá a matriz uma linha por elemento.
fonte
Excel VBA, 204 bytes
Função de janela imediata VBE anônima que leva a entrada do intervalo
[A1]
e as saídas para o objeto ActiveSheetResultado
fonte