Códigos de barras de 4 estados
Muitos serviços postais (Royal Mail UK, Correio do Canadá, Correio dos EUA, etc.) usam um código de barras de quatro estados para codificar informações sobre seus e-mails. Renderizado em ASCII, pode ser algo como isto:
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Um código de barras de 4 estados é uma linha de barras. Cada barra pode ser estendida para cima, para baixo ou ambas, permitindo quatro possibilidades. Isso significa que cada barra representa essencialmente um dígito de base 4:
| | Bar: | | | | | | Dígito: 0 1 2 3
O problema com esta simbologia é que cada código de barras é um código de barras diferente válido e de cabeça para baixo: alterando drasticamente o significado se a orientação estiver incorreta. Portanto, uma sequência de início e parada é normalmente implementada para que o scanner possa calcular de que maneira deve ser lido.
Para o objetivo deste desafio, usaremos a sequência de início / parada especificada pelo Australia Post: cada código de barras começa e termina com uma 1 0
sequência.
O desafio
Sua tarefa é escrever um programa ou função que, dado um número inteiro positivo N
, o converta em um código de barras ASCII de 4 estados, onde cada barra (exceto as seqüências de início / parada) representa um dígito na representação de base 4 de N
.
Exemplo:
Dado o número inteiro 19623
, primeiro o converteríamos em sua representação base-4 10302213
,.
Em seguida, mapeamos cada dígito para a barra correspondente:
1 0 3 0 2 2 1 3 | | | | | | | | | | | | | | | |
Por fim, adicionaríamos as seqüências de início / parada:
Inicio fim: 1 0 1 0 | | | | | | | | | | | | | | | | | | | | | |
O código de barras resultante deve ser a saída do programa.
Regras:
- A entrada será um número inteiro positivo, dentro do intervalo do tamanho inteiro padrão do seu idioma.
- A saída:
- Pode ser uma lista de linhas ou uma sequência contendo novas linhas.
- Pode conter novas linhas / espaços iniciais ou finais, desde que a forma permaneça intacta.
- Deve mostrar o código de barras com o formato acima - ele deve usar o caractere de barra vertical (
|
) e o caractere de espaço () ao desenhar barras, e deve haver 1 espaço entre cada barra vertical.
- Isso é código-golfe , então o programa mais curto (em bytes) vence!
Casos de teste
4095:
| | | | | | | | | | | | | | | | | | | | | | | |
4096:
| | | | | | | | | | | | | |
7313145:
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
fonte
Respostas:
Python 3 ,
1039996 bytesExperimente online!
fonte
MATL ,
34302928 bytesExperimente online!
Explicação
fonte
Geléia ,
1615 bytesExperimente online!
Como funciona
fonte
.......
mas cada ponto representa um byte diferente.Geléia , 19 bytes
Experimente online!
-1 graças ao Sr. Xcoder .
fonte
Oitava ,
78 77 75 74 7069 bytesExperimente online!
Diferentemente da abordagem original, esta usa uma tabela de pesquisa simples para mapear os valores da base-4 em seu equivalente binário. A tabela de pesquisa também adiciona o espaçamento entre cada barra, adicionando um zero entre cada número (que é mapeado para uma barra de todos os espaços).
A tabela de pesquisa é mapeada diretamente para as barras como:
A conversão de binário para
|
eagora é feita indexando em uma sequência desses dois caracteres - basicamente o mesmo princípio da tabela de pesquisa para conversão binária.
* Salvo 1 byte, obrigado @LuisMendo
Original:
Experimente online!
Função anônima que retorna o código de barras como uma string.
Isso se baseia no fato de que se adicionarmos 4 aos dígitos base4, poderemos representar barra / espaço pelo número convertido em binário com os bits 1 e 2 trocados:
A parte complicada do ponto de vista do golfe é adicionar os espaços entre as barras e converter de
0/1
para'|'/' '
.fonte
JavaScript (ES6),
898783 bytesCasos de teste
Mostrar snippet de código
Quão?
Nota : na versão abaixo, os literais de modelo foram substituídos por sequências padrão para que o código possa ser recuado corretamente.
fonte
R ,
154109 bytesExperimente online!
Salvou um monte de bytes indexando e usando
cat
vez de construir uma matriz e usandowrite
, além de 6 de uma conversão ligeiramente diferente para a base 4. Imprime com um espaço à esquerda em cada linha e sem novas linhas à direita.A indexação ocorre usando alguma aritmética modular, não diferente de outras respostas, mas como R usa a indexação baseada em 1, a aritmética é um pouco diferente.
Explicação:
fonte
Carvão , 50 bytes
Experimente online! Link é a versão detalhada do código. Explicação:
Digite um número.
Empurre a sequência de parada para a lista vazia predefinida.
Se o número for positivo,
aplique repetidamente o divmod para convertê-lo na base reversa 4,
caso contrário, basta empurrá-lo.
Empurre a sequência inicial para a lista.
Mapeie mais de três strings. Cada sequência representa a tradução do código de barras para os dígitos
0123
de cada linha.Mapeie os dígitos (revertidos para a ordem usual), converta-os em barras ou espaços usando a tradução e junte os resultados em três cadeias que são impressas implicitamente em linhas separadas.
fonte
Japonês ,
3231 bytesTeste online!
Ainda não estou satisfeito com isso, mas é um começo ...
Explicação
fonte
Haskell ,
9190 bytesExperimente online!Retorna uma lista de linhas.
Alternativa de contagem de mesmos bytes para a primeira linha:
fonte
J ,
57 4947 bytes10 bytes graças ao FrownyFrog!
Como funciona:
1 0,4&#.inv,1,0:
- converte o número em uma lista de dígitos da base 4, adiciona 1 0 ao início e ao final da lista((#:2 6 3 7){' |')
- tabela de pesquisa para a criptografia, o binário 0 corresponde ao espaço, 1 a '|'{~
- criptografa o dígito base 4, selecionando uma string da tabela de pesquisa acima (argumento invertido)|:
- transpõe a matriz resultante de 3 colunas para 3 linhas[:
- tampe o garfo,.2{."0
- coloca espaços entre as barrasExperimente online!
fonte
APL + WIN, 63 bytes
Explicação:
fonte
Python 2 ,
116114 bytes-2 bytes graças a notjagan
Experimente online!
fonte
05AB1E , 19 bytes
Experimente online!
Essa é uma meia porta da abordagem de Dennis, que é apenas um byte menor que o método que eu usei antes (com o qual estou muito feliz):
05AB1E , 20 bytes
Experimente online!
Como funciona?
Perguntei a Adnan (o criador do 05AB1E) sobre o grid no chat , e eles me ajudaram a economizar 2 bytes, apontando um recurso do 05AB1E: ao ingressar em listas multi-dimensionais por novas linhas, as listas internas também são unidas por espaços , então
ðý
é desnecessário.fonte
APL (Dyalog Classic) , 33 bytes
Experimente online!
fonte
2⊥⍣¯1
como você obteria uma lista binária?2⊥⍣¯1
é o inverso ("anverso"?) De "decodificação dupla". Ele codifica em binário com quantos bits forem necessários.J ,
42 4039 bytesRaspou 2 bytes graças a Dennis. 1 byte graças a ngn.
Experimente online!
Como funciona
fonte
JavaScript (ES6) 79 bytes
Usa .toString para converter o número em base 4 e, em seguida, consulta com cada linha e OR bit a bit para criar a linha de saída por linha. Produz uma lista de linhas.
fonte
`10${n.toString(4)}10`
:)Bash + coreutils,
7167 bytesExperimente online!
Explicação
O
dc
bit se converte na base 4, acrescentando e anexando com um4
(transforma-se10
na saída) e usandon
para manter tudo em uma linha.O resto acontece em
sed
:fonte
x
os espaços de espera / padrão ao redor para modificá-los e depois fazers
tudo de uma vez, e nada acabou mais curto.Retina , 83 bytes
Experimente online! O link inclui os casos de teste mais rápidos. Explicação:
Converta para unário.
Converta na base 4 como números unários separados por
;
s.Anexe a sequência inicial.
Acrescente a
;
, transformando-o em um terminador de dígitos, em vez de um separador, e a sequência de parada.Converta em decimal, mas adicionando 1 a cada dígito.
Triplicar isso.
Na primeira linha,
1
s e3
s (representando0
s e2
s) tornam-se espaços.Na última linha,
1
s e2
s (representando0
s e1
s) tornam-se espaços.Todos os outros dígitos se tornam barras.
fonte
Pip ,
3331292726 bytes25 bytes de código, +1 para
-S
sinalizador.Experimente online!
Explicação
Observamos um padrão nos quatro tipos de barra:
Tão:
fonte
SOGL V0.12 , 28 bytes
Experimente aqui!
fonte
C (gcc) , 176 bytes
Experimente online!
Um pouco menos terrivelmente formatado (menos golfe):
Explicação
Primeiro, considere o código a seguir para ler um número inteiro e gerar a versão base 4:
Isso usa a recursão de cauda para reverter a ordem da saída. Cada passo recursivo muda de bits em 2 (corta os últimos 2 bits e divide em 4). Ele gera o resultado com máscara de bits com 3 (0b11), que mostra apenas os dois últimos bits, que é a última base de dígitos 4.
A chamada de função é incluída no
printf
argumento como final (não é impressa, mas é avaliada) para evitar a necessidade de usar {} (+2 bytes) para agrupar oprintf
chamada de função e.A solução aqui estende esse código base-4. Primeiro, m é definido como n, mas tal que na base 4 ele terá 10 anexados e anexados a ele. Em seguida, imprimimos m.
Na impressão base 4 regularmente, usamos uma máscara de bit 3 para obter o dígito. No código de correio, a linha superior é o bit de ordem inferior desse dígito (uma máscara de bit 1) e a linha inferior é o bit de ordem superior (uma máscara de bit 2). Consequentemente, o
r
inf(n,r)
é a máscara de bits - nossa principal função exigef(m,1)
a primeira linha ef(m,2)
a última linha.Para fazer a linha do meio funcionar (sempre imprima "|"), adicionamos
||!r
à condicional - se r for 0, ela sempre será avaliada como verdadeira e imprimirá uma "|". Então chamamosf(m,0)
a linha do meio.Finalmente, queremos que as novas linhas se comportem. Incluir um extra
printf
é caro no que diz respeito a bytes de código-fonte; portanto, adicionamos outro especificador% c ao existenteprintf
.n?32:10
imprime uma nova linha se n for 0 (falso) e um espaço caso contrário. 32 e 10 são usados em vez de '\ n' e '' para salvar bytes.fonte
f(n,r){n&&f(n>>2);printf("%c%c",n?32:10,(n&r|!r)&&n?'|':32);}main(n){scanf("%d",&n);f(n=(n+(4<<(32-__builtin_clz(n)/2*2)))*16+4,1);f(n,0);f(n,2);}
Lisp comum, 191 bytes
Experimente online!
fonte
PHP, 99 + 1 bytes
requer PHP> = 5.5 para indexação literal de cadeias e <7.1 para que a indexação não produza um aviso.
Executar como tubo com
-nR
ou experimente online .Insira mais uma nova linha para obter uma à direita.
fonte
Python 2,
142126 bytesMuito obrigado aos ovs!
Tentei não copiar os métodos das outras respostas e ... eca.
fonte
C # (.NET Core) , 160 bytes
Experimente online!
Tenho certeza de que perdi algumas melhorias.
DeGolfed
t<51 & y != 1 & t-(y>>1) != 49
verifica se o caractere não é '3', não a segunda linha e, em seguida, alguma mágica binária para ver se a primeira ou a terceira linha deve conter o espaço.fonte
Zsh ,
156154151133 bytesExperimente online!
Obtém a entrada da base 10 do var
$x
fonte
Japonês , 42 bytes
Experimente online!
fonte
Pitão , 32 bytes
Experimente aqui!
fonte
C, 120 bytes
Infelizmente, só funciona no Windows, pois
itoa
é muito conveniente para ser padrão.fonte