Para los fanáticos de nandgame: ¡prueba DPD a decimal en puertas lógicas también!
Fondo
El decimal denso (DPD) es una forma de almacenar eficientemente dígitos decimales en binario. Almacena tres dígitos decimales (000 a 999) en 10 bits, que es mucho más eficiente que el BCD ingenuo (que almacena un dígito en 4 bits).
Anotaciones
- Las letras minúsculas
a
ai
son los bits que se copian en la representación decimal. 0
y1
son los bits exactos en los patrones de bits de entrada o salida.x
los bits se ignoran en la conversión.
Tabla de conversión
La siguiente es la tabla de conversión de 10 bits de DPD a tres dígitos decimales. Cada dígito decimal se representa como binario de 4 bits (BCD). Ambas partes se escriben de izquierda a derecha desde el dígito más significativo al menos.
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)
Tarea
Convierta 10 bits de DPD a 3 dígitos de decimal.
Casos de prueba
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
El formato de entrada predeterminado es una lista de 10 bits. Los bits deben seguir el orden exacto anterior o al revés. Puede optar por utilizar una cadena equivalente o una representación entera en su lugar. A diferencia de mis otros desafíos, reordenar o usar estructuras anidadas no está permitido .
Para la entrada [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
, se permiten los siguientes formatos:
- Lista de bits:
[1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
- Cuerda:
"1100010100"
- Entero binario:
788
o0b1100010100
- Entero decimal:
1100010100
- Invertido:
[0, 0, 1, 0, 1, 0, 0, 0, 1, 1]
e invertido en cualquier otro formato anterior
Los siguientes formatos NO están permitidos:
- Reordenamiento arbitrario de bits:
[0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
- Estructuras anidadas:
[[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]
o[0b110, 0b001, 0b0100]
Salida
El formato de salida predeterminado es una lista de 3 dígitos decimales. Cada dígito debe representarse como 0 a 9, ya sea un entero o un carácter. Como en la entrada, puede elegir la representación de cadena o de enteros. Si elige la representación de enteros, se pueden omitir los ceros a la izquierda.
Criterio de puntuación y ganador
Aplican reglas estándar de código de golf . El programa o función más corto en bytes para cada idioma gana.
fuente
Python 3 ,
229 ... 9796 bytesPruébalo en línea!
-4 bytes por @xnor
-6 bytes por @nwellnhof
Formateado:
Explicación
Debido a que originalmente quería implementar esto en Jelly, adopto un enfoque diferente de la mayoría de las respuestas aquí, que es simple y quizás adecuado para un lenguaje de golf. Aunque la función de golf toma un número entero, deje que la entrada como una lista de bits sea
[a0,a1,...,a9]
. Entonces podemos derivar tres valores de la entrada[a2,a5,a9]
: siempre serán los bits bajos de[d0,d1,d2]
respectivamente.[2*a0a1,2*a3a4,2*a7a8,8]
: los bits altos de cada dígito serán uno de estos.[a3,a4,a5,a7,a8]
, que determinan cómo obtener los bits altos de cada dígito. Calculamos el indicador (entre 1 y 8) de la siguiente manera:Luego, el enésimo dígito se puede calcular con elegancia como
high_bits[arr[indicator][n]] | low_bits[n]
en la tabla a continuación, que se comprime en una cadena.fuente
b"..."
de bytes para reemplazar la conversión conord
.b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)]
guarda otros cuatro bytes.JavaScript (Node.js) ,
126119117112111 bytesPruébalo en línea!
-5 bytes gracias @tsh (y 2 solo) Así que
l
puedo hacer más esfuerzo de lo que esperaba.-2 bytes más usando la técnica de @ tsh!
-5 bytes gracias @Arnauld
-1 byte gracias @Neil
Entrada como una lista de 10 bits (como 10 argumentos), salida como una lista de 3 dígitos.
fuente
(!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)
guarda otro byte. (Lo comprobé esta vez ...)C (gcc) ,
138129 bytesPruébalo en línea!
Primero extrae algunos bits en variables
s
yt
, para que las ocho filas de la tabla de conversión puedan identificarse mediante:Luego se configura
u
yv
con divisiones (desplazamiento a la derecha), de modo queu
,v
y la entradaw
contiene los tres bits BCD inferiores en las posiciones 0-2. El resto es un poco aleatorio dependiendo des
yt
. Dos trucos notables son:Un puerto de la solución Javascript de Shieru Asakoto tiene solo 124 bytes :
Pruébalo en línea!
fuente
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 ... 119117bytesPruébalo en línea!
Cómo funciona:
Este es el punto de partida: convierta a BCD desplazando 3 bits a la izquierda, lo que funciona para la mayoría de los patrones.
Obtenga los bits medios de cada mordisco (y un bit extra del tercer mordisco, pero enmascare el bit menos significativo).
Si el tercer dígito es menor que 10 (menor que 9 porque de todos modos nunca nos importó el LSB), estamos listos: esto es BCD simple, podemos generar el hexadecimal sin cambiar nada
De lo contrario, haz algo de magia negra cambiando los bits y agregando números mágicos hasta que obtengamos el resultado que queremos.
fuente
Retina 0.8.2 ,
191181 bytesPruébalo en línea! El enlace incluye casos de prueba. Editar: guardado 10 bytes al no rellenar dígitos a 4 bits, excepto cuando sea necesario. Explicación:
Inserte separadores para que cada dígito se pueda convertir a decimal por separado. Esto maneja efectivamente los dos primeros casos en la tabla de conversión.
Maneje el último (octavo) caso en la tabla de conversión.
Manejar los casos sexto y séptimo en la tabla de conversión.
Manejar el quinto caso en la tabla de conversión.
Manejar los casos tercero y cuarto en la tabla de conversión.
Realizar conversión de binario a decimal.
fuente
Jalea ,
51484039 bytesPruébalo en línea!
Algoritmo
Con la excepción de los índices de lista, todos los enteros en esta sección están escritos en binario.
Entrada dadaα βγδε ζηθ ι κ , primero construimos las matrices [ ηη, θ ι , δε ] , [ α β, δε , θ ι ] y [ γ, ζ, κ ] .
Si contamos el número de líderes11 's [ ηη, θ ι , δε ] , cree una matriz de un número coincidente de 100 's, concatenarlo con [ α β, δε , θ ι ] y dividimos el resultado en submatrices de longitud tres, obtenemos los siguientes resultados en cada caso.
En el primer y último caso, solo tenemos que comprimir la primera matriz con[ γ, ζ, κ ] , cediendo [ α βγ, δε ζ, θ ι κ ] en el primer caso y [ 100 γ, 100 ζ, 100 κ ] en el último.
Los dos casos restantes son similares, pero las matrices[ 100 , α β, δε ] y [ 100 , 100 , α β] tiene que ser reordenado, de acuerdo con los valores de [ θ ι ] y posiblemente δε .
En el segundo caso, las seis permutaciones de[ 100 , α β, δε ] son [ 100 , α β, δε ] , [ 100 , δε , α β] , [ α β,100,δε] , [αβ,δε,100] , [δε,100,αβ] , and [δε,αβ,100] .
By computing100−θι , we map 00 , 01 , and 10 to four, three and two, selecting the permutations [αβ,δε,100] , [αβ,100,δε] , and [100,δε,αβ] .
After zipping the result with[γ,ζ,κ] , we get [αβγ,δεζ,100κ] , [αβγ,100ζ,δεκ] , or [100γ,δεζ,αβκ] .
In the third case, the permutations (with duplicates) of[100,100,αβ] are [100,100,αβ] , [100,αβ,100] , [100,100,αβ] , [100,αβ,100] , [αβ,100,100] and [αβ,100,100] .
By computing(100−θι)−(100−δε)=δε−θι=δε−11 , we map 00 , 01 , and 10 to three, four, and five modulo six, selecting the permutations [100,100,αβ] , [100,αβ,100] , and [αβ,100,100] .
After zipping the result with[γ,ζ,κ] , we get [100γ,100ζ,αβκ] , [100γ,αβζ,100κ] , or [αβγ,100ζ,100κ] .
Code
fuente
Python 2, 157 bytes
Try it online!
fuente
Clean,
238... 189 bytes-2 bytes thanks to Neil
Try it online!
Takes a 'list' of 10 bits in the form of 10 arguments, using a direct formula to compute the result.
fuente
i*(9*e+19*d+i*...)
, that secondi*
looks unnecessary.Perl 5, 195 bytes
Try it online
I know 195 bytes is far too much for this contest, but I had no idea how to further compress the Perl code. Suggestions?
Explanation of the code
In a more readable version, the code intention should become apparent:
In the rules for DPD encoding, each line is encoded into a 18 bit value, segmentation into (6,6,(2,2,2)) bits.
@p
for the 3-bit sequences which are to spliced into bits 11-9, 7-5 and 3-1 of the result.@p
is constructed from bits 9-8, 6-5, 3-2 of the input, and the number8
as fourth memberFor example, the first number in the list,
16390
, which is100000000000110
as a bit field, carries the following information:fuente
05AB1E, 84 bytes
Port of KimOyhus' answer to 05AB1E.
Try it online!
Rough explanation:
fuente
05AB1E,
104103101 bytesDefinitely not the right language for this kind of challenge, but ah well..
Input as string, output as list of three digits.
Try it online or verify all test cases.
Explanation:
We have the following eight scenarios to consider:
I first split the (implicit) input into chunks of size
[2,1,2,1,3,1]
and store that list in the register:See this 05AB1E tip of mine (section How to compress large integers?) to understand why
•3γã•
is212131
Now we're first going to built the 0s and 1s for the first digit of the output. Scenarios 1,2,3,7 use
'0'+1st+2nd
; and scenarios 4,5,6,8 use'100'+2nd
:Then we're going to built the 0s and 1s for the second digit of the output. Scenarios 1,2,4 use
'0'+3rd+4th
; scenarios 3,5,7,8 use'100'+4th
; and scenario 6 uses'0'+1st+4th
:Then we're going to built the 0s and 1s for the third digit of the output. Scenarios 1,2 use
5th+6th
; scenario 3 uses'0'+3rd+6th
; scenarios 4,5 use'0'+1st+6th
; and scenarios 6,7,8 use'100'+6th
:Now we have all 0s and 1s on the stack, so we can convert it to the three output digits:
fuente