Para fãs de nandgame: Por favor, experimente DPD para decimal em portas lógicas também!
fundo
O decimal densamente compactado (DPD) é uma maneira de armazenar com eficiência dígitos decimais em binário. Ele armazena três dígitos decimais (000 a 999) em 10 bits, o que é muito mais eficiente que o BCD ingênuo (que armazena um dígito em 4 bits).
Notações
- As letras minúsculas
a
parai
são os bits que são copiados para a representação decimal. 0
e1
são os bits exatos nos padrões de bits de entrada ou saída.x
bits são ignorados na conversão.
Tabela de conversão
A seguir, a tabela de conversão de 10 bits do DPD para três dígitos decimais. Cada dígito decimal é representado como binário de 4 bits (BCD). Ambos os lados são escritos da esquerda para a direita, do dígito mais significativo ao mínimo.
Bits => Decimal (Digit range)
a b c d e f 0 g h i => 0abc 0def 0ghi (0-7) (0-7) (0-7)
a b c d e f 1 0 0 i => 0abc 0def 100i (0–7) (0–7) (8–9)
a b c g h f 1 0 1 i => 0abc 100f 0ghi (0–7) (8–9) (0–7)
g h c d e f 1 1 0 i => 100c 0def 0ghi (8–9) (0–7) (0–7)
g h c 0 0 f 1 1 1 i => 100c 100f 0ghi (8–9) (8–9) (0–7)
d e c 0 1 f 1 1 1 i => 100c 0def 100i (8–9) (0–7) (8–9)
a b c 1 0 f 1 1 1 i => 0abc 100f 100i (0–7) (8–9) (8–9)
x x c 1 1 f 1 1 1 i => 100c 100f 100i (8–9) (8–9) (8–9)
Tarefa
Converta 10 bits do DPD em 3 dígitos decimais.
Casos de teste
DPD Decimal
0000000101 005
0001100011 063
0001111001 079
0000011010 090
0001011110 098
1010111010 592
0011001101 941
1100111111 879
1110001110 986
0011111111 999
1111111111 999 * Output is same regardless of the `x` bits
Entrada
O formato de entrada padrão é uma lista de 10 bits. Os bits devem seguir a ordem exata acima, ou o inverso. Você pode optar por usar uma sequência equivalente ou uma representação inteira. Ao contrário dos meus outros desafios, não é permitido reordenar ou usar estruturas aninhadas .
Para a entrada [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
, os seguintes formatos são permitidos:
- Lista de bits:
[1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
- Corda:
"1100010100"
- Inteiro binário:
788
ou0b1100010100
- Inteiro decimal:
1100010100
- Invertida:
[0, 0, 1, 0, 1, 0, 0, 0, 1, 1]
e invertida em qualquer outro formato acima
Os seguintes formatos NÃO são permitidos:
- Reordenação arbitrária de bits:
[0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
- Estruturas aninhadas:
[[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]
ou[0b110, 0b001, 0b0100]
Saída
O formato de saída padrão é uma lista de 3 dígitos decimais. Cada dígito deve ser representado como 0 a 9, um número inteiro ou um caractere. Como na entrada, você pode escolher uma representação de sequência ou número inteiro. Se você escolher representação inteira, os zeros à esquerda poderão ser omitidos.
Critério de pontuação e vitória
Aplicam-se as regras de código-golfe padrão . O programa ou função mais curto em bytes para cada idioma vence.
fonte
Python 3 ,
229 ... 9796 bytesExperimente online!
-4 bytes por @xnor
-6 bytes por @nwellnhof
Formatado:
Explicação
Como eu originalmente queria implementar isso no Jelly, adoto uma abordagem diferente da maioria das respostas aqui, que é simples e talvez adequada para uma linguagem de golfe. Embora a função golfed use um número inteiro, deixe a entrada como uma lista de bits
[a0,a1,...,a9]
. Então podemos derivar três valores da entrada[a2,a5,a9]
: sempre serão os bits baixos[d0,d1,d2]
respectivamente.[2*a0a1,2*a3a4,2*a7a8,8]
: os bits altos de cada dígito serão um deles.[a3,a4,a5,a7,a8]
, determinando como obter os bits altos de cada dígito. Calculamos o indicador (entre 1 e 8) da seguinte forma:Em seguida, o enésimo dígito pode ser calculado com elegância, conforme
high_bits[arr[indicator][n]] | low_bits[n]
a tabela abaixo, que é compactada em uma string.fonte
b"..."
para substituir a conversãoord
.b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)]
salva outros quatro bytes.JavaScript (Node.js) ,
126119117112111 bytesExperimente online!
-5 bytes obrigado @tsh (e 2 por mim) Portanto,
l
podemos fazer mais esforço do que eu esperava.-2 mais bytes usando a técnica de @ tsh!
-5 bytes obrigado @Arnauld
-1 byte obrigado @Neil
Entrada como uma lista de 10 bits (como 10 argumentos), saída como uma lista de 3 dígitos.
fonte
(!i|!d|e)
->i+l!=5
;(d|e|!h)
->h+l!=1
(g?h-i|h&!e?h?b:e:8:h*4+i*2)
->(g?h<i?e:h>i*e?b:8:h*4+i*2)
salva outro byte. (Verifiquei desta vez ...) #C (gcc) ,
138129 bytesExperimente online!
Primeiro extrai alguns bits em variáveis
s
et
, para que as oito linhas da tabela de conversão possam ser identificadas por:Em seguida, ajusta-se
u
ev
com divisões (deslocamentos para a direita), para queu
,v
e a entrada dew
conter os mais baixos três BCD bits em posições 0-2. O resto é um pouco aleatório, dependendo des
et
. Dois truques notáveis são:Uma porta da solução Javascript de Shieru Asakoto tem apenas 124 bytes :
Experimente online!
fonte
f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
Ruby ,
153 ... 119117 bytesExperimente online!
Como funciona:
Este é o ponto de partida: converta para BCD deslocando 3 bits para a esquerda, o que funciona para a maioria dos padrões.
Obtenha os bits do meio de cada petisco (e um bit extra do terceiro petisco, mas oculte o bit menos significativo).
Se o terceiro dígito for menor que 10 (menor que 9, porque nunca cuidamos do LSB de qualquer maneira), estamos definidos: este é o BCD simples, podemos gerar o hex sem alterar nada
Caso contrário, faça alguma magia negra mudando os bits e adicionando números mágicos até obter o resultado desejado.
fonte
Retina 0.8.2 ,
191181 bytesExperimente online! O link inclui casos de teste. Editar: economizou 10 bytes por não preencher dígitos de 4 bits, exceto onde necessário. Explicação:
Insira separadores para que cada dígito possa ser convertido em decimal separadamente. Isso efetivamente lida com os dois primeiros casos na tabela de conversão.
Manipule o último (oitavo) caso na tabela de conversão.
Manipule os sexto e sétimo casos na tabela de conversão.
Manipule o quinto caso na tabela de conversão.
Manipule o terceiro e o quarto casos na tabela de conversão.
Realize a conversão de binário em decimal.
fonte
Geléia ,
51484039 bytesExperimente online!
Algoritmo
Com exceção dos índices da lista, todos os números inteiros nesta seção são gravados em binário.
No terceiro caso, as permutações (com duplicatas) de[ 100 , 100 , α β] [ 100 , 100 , α β] [ 100 , α β, 100 ] [ 100 , 100 , α β] [ 100 , α β, 100 ] [ α β, 100 , 100 ] [ α β, 100 , 100 ]
Código
fonte
Python 2 , 157 bytes
Experimente online!
fonte
Limpo ,
238... 189 bytes-2 bytes graças a Neil
Experimente online!
Leva uma 'lista' de 10 bits na forma de 10 argumentos, usando uma fórmula direta para calcular o resultado.
fonte
i*(9*e+19*d+i*...)
, esse segundoi*
parece desnecessário.Perl 5, 195 bytes
Experimente online
Eu sei que 195 bytes é demais para este concurso, mas eu não tinha idéia de como compactar ainda mais o código Perl. Sugestões?
Explicação do código
Em uma versão mais legível, a intenção do código deve se tornar aparente:
Nas regras para codificação DPD, cada linha é codificada em um valor de 18 bits, segmentação em bits (6,6, (2,2,2)).
@p
para as sequências de 3 bits que devem ser unidas nos bits 11-9, 7-5 e 3-1 do resultado.@p
é construída a partir dos bits 9-8, 6-5, 3-2 da entrada e o número8
como quarto membroPor exemplo, o primeiro número da lista
16390
, que é100000000000110
um campo de bits, carrega as seguintes informações:fonte
05AB1E , 84 bytes
Resposta do porto de KimOyhus para 05AB1E.
Experimente online!
Explicação aproximada:
fonte
05AB1E ,
104103101 bytesDefinitivamente, não é o idioma certo para esse tipo de desafio, mas sim.
Entrada como string, saída como lista de três dígitos.
Experimente online ou verifique todos os casos de teste .
Explicação:
Temos os seguintes oito cenários a serem considerados:
Primeiro, divido a entrada (implícita) em pedaços de tamanho
[2,1,2,1,3,1]
e armazeno essa lista no registro:Veja este 05AB1E ponta do meu (seção Como comprimir grandes inteiros? ) Para entender por que
•3γã•
é212131
Agora vamos construir os 0s e 1s para o primeiro dígito da saída. Cenários 1,2,3,7 usam
'0'+1st+2nd
; e os cenários 4,5,6,8 usam'100'+2nd
:Então, vamos construir os 0s e 1s para o segundo dígito da saída. Cenários 1,2,4 usam
'0'+3rd+4th
; cenários 3,5,7,8 uso'100'+4th
; e o cenário 6 usa'0'+1st+4th
:Então, vamos construir os 0s e 1s para o terceiro dígito da saída. Cenários 1,2 de uso
5th+6th
; cenário 3 usa'0'+3rd+6th
; cenários 4,5 uso'0'+1st+6th
; e cenários 6,7,8 usam'100'+6th
:Agora temos todos os 0 e 1 na pilha, para que possamos convertê-lo nos três dígitos da saída:
fonte