Reto
Su tarea es codificar un número entero como una cadena de caracteres ASCII , luego decodificarlo con éxito después de que dicha cadena se haya barajado aleatoriamente.
Escribirás dos programas / funciones , que se denominarán codificador y decodificador. .
Codificador
- Entrada: un número entero en el rango .
- Salida: una cadena de ASCII caracteres (no necesariamente imprimible).
Descifrador
- Entrada: una permutación aleatoria de la cadena .
- Salida: el entero .
Tanteo
Sea la longitud máxima de en todos los valores posibles de . Si el codificador actúa de manera no determinista (lo cual está permitido, ver más abajo), entonces la será la longitud máxima de que puede ocurrir (posiblemente ).
Sea la longitud del codificador en bytes y la longitud del decodificador en bytes.
Entonces su puntaje es .
La victoria se otorga a la presentación la puntuación más baja .
Límite de tiempo
Hay un límite de tiempo algo arbitrario de 1 minuto en el tiempo de ejecución tanto del codificador como del decodificador para un solo caso de prueba (es decir, un único valor de ).
El objetivo es evitar una solución que encuentre que la fuerza bruta codifica enumerando todas las secuencias con ciertas propiedades. Si su solución hace algo más inteligente que eso, lo más probable es que se ajuste a la restricción de tiempo y se considerará válida. Del mismo modo, si funciona en TIO para algunos valores seleccionados al azar de , se considerará válido. De lo contrario, lo probaré en mi máquina, pero tenga en cuenta que si su solución es pura fuerza bruta, seguramente fallará.
Reglas
- El codificador y el decodificador deben estar escritos en el mismo idioma .
- El decodificador debe generar el número entero correcto para cada permutación posible de la cadena devuelta por elcodificador.
- El codificador y el decodificador se no se les permite compartir información de cualquier forma (por ejemplo, por medio de variables globales o archivos).
- La salida del codificador no necesita ser determinista (es decir, la misma entrada puede producir diferentes cadenas de salida si el codificador se ejecuta varias veces), pero el decodificador siempre debe adivinar el número entero correcto .
- El codificador y el decodificador pueden tomar y devolver el número entero de cualquier manera conveniente (por ejemplo, si está bien que la entrada sea
14
,"14"
o[1,4]
). - El codificador puede emitir la cadena ya sea por impresión en
stdout
o por devolver una cadena, una lista / matriz de caracteres o una lista / matriz de enteros en el intervalo ; tenga en cuenta que el decodificador recibirá como entrada una permutación de devuelta por el codificador , por lo que debe aceptar la cadena en el mismo formato que . - Las lagunas estándar están prohibidas.
- Si es posible, explique cómo funciona su código y por qué el puntaje que reclama es correcto.
Ejemplo
Suponga que .
- El codificador recibe
14
como entrada. Puede salir"qwerty"
.- El decodificador recibe una permutación
"qwerty"
como entrada, por ejemplo"tweyqr"
. Debe salir14
(en cualquier formato conveniente).
El codificador podría haber regresado[113,119,101,114,116,121]
, en cuyo caso el decodificador habría recibido (por ejemplo) [116,119,101,121,113,114]
.
Tenga en cuenta que la cadena devuelta por el codificador también puede incluir caracteres ASCII no imprimibles (pero siempre en el rango[0x00, ..., 0x7F]
).
Respuestas:
Gelatina , (17 bytes + 18 bytes) × longitud 6 = 210 puntos
Pruébalo en línea! (o con información adicional de depuración)
Después de haber intentado resolver este desafío con el objetivo de la condición de victoria establecida, pensé que sería interesante optar por una condición de victoria alternativa hipotética: el golf de código dado una longitud máxima posible mínima para la salida.
Explicación
Codificación
El primer paso en la codificación es representar la entrada como base 36 (
b36
). 36 6 = 2176782336> 2147483647, por lo que habrá como máximo 6 dígitos en el resultado, cada uno de los cuales está en el rango 0–35.A continuación, transformamos esto en una representación que contiene 6 dígitos diferentes . Hay varios algoritmos posibles para esto, pero el que se usa aquí es agregar 1 al dígito más pequeño, 2 al segundo más pequeño, 3 al tercero más pequeño, y así sucesivamente. Esto significa que si dos dígitos fueran iguales, uno de ellos se considerará arbitrariamente más pequeño y, por lo tanto, se volverán diferentes; y obviamente, este algoritmo no puede causar que dos dígitos diferentes se vuelvan iguales. Para representar esto en Jelly, utilizamos
Ụ
("ordenar índices por valores") para obtener una lista de los índices en orden; para agregar el original a la nueva lista. El resultado es una representación del número de entrada como seis dígitos diferentes en el rango 1-41 (mínimo 0 + 1, máximo 35 + 6).Ụ
nuevamente para invertir eso, mapeando efectivamente cada elemento del original a su posición en orden ordenado; yµ…+
Luego dividir esto en otra forma: una ordenada lista de dígitos en el rango 1-41, junto a un número del 1 al 720 que representa cuál de las 720 permutaciones posibles los dígitos estaban en (El.
Œ¿
YṢ
extraer el número de permutación y ordenados lista respectivamente.)Finalmente, convertimos el número del 1 al 720 en la base 3 (
b3
), lo invertimos (U
) y codificamos los seis dígitos de la base 3 y los seis dígitos del 1 al 41 empaquetándolos en un solo carácter ASCII usando el divmod inverso (el valor de el carácter mod 3 es el dígito base 3, el valor dividido entre 3 es el 1-41 dígito). El rango posible de resultados es (1 × 3) + 0 = 3 como mínimo, y (41 × 3) + 2 = 125 como máximo, dentro de nuestro rango ASCII. El empaquetado se realiza a través de×3
y+
, junto con un adicionalµ
para asegurarse de que cada comando opere en el bit de datos correcto. (Aquí hay un pequeño truco de golf, ya que hacemos la multiplicación por 3 antes de extraer la permutación; eso ahorra la necesidad de gastar un byte en un personaje de agrupación).Por cierto, la razón para invertir el número base 3 es porque puede tener menos dígitos que el número 1–41. (No puede tener más; ¡el número más pequeño para el que n !> 3 n está ligeramente por encima de 6.) Jelly inserta efectivamente ceros finales al sumar dos números de diferentes longitudes, para que coincidan; los ceros finales afectarían la interpretación del número, pero los ceros iniciales no lo harían, por lo que lo inverso se usa para garantizar que los ceros adicionales terminen en algún lugar que no estropee nuestra respuesta.
Descodificación
El primer paso en la decodificación es extraer los dos números (el número base 3 y el número 1-41). Podemos obtener sus dígitos con bastante facilidad con division (
:3
) y modulo (%3
) respectivamente, pero ¿cómo saber en qué orden estaban? Bueno, el número 1–41 tenía sus dígitos en orden ordenado, y los dígitos en las posiciones correspondientes de los dos números se almacenaban en los mismos caracteres; por lo tanto, podemos determinar en qué orden se barajaron los dígitos del número 1–41 (observando sus valores relativos) y saber que los dígitos del número base 3 deben haberse barajado de la misma manera. De hecho, debido a que los caracteres de nuestra codificación ASCII se ordenan de la misma manera que los dígitos del número 1–41 (todos eran distintos y son más significativos que los números de la base 3),Ṣ
. Entonces, ambas extracciones comienzan conṢ
, seguidas de%3
o:3
según corresponda.Si bien los dígitos del número 1–41 todavía están ordenados, tenemos una forma muy conveniente / concisa de volver a los 0–35 dígitos de la base 36; solo resta 1 del primero, 2 del segundo, 3 del tercero, y así sucesivamente. En Jelly, podemos hacer eso con
_J
("índice de resta").Mientras tanto, en la otra rama de la decodificación, revertimos los dígitos del número de la base 3 nuevamente en orden (
U
), y lo convertimos de la base 3 nuevamente en un índice de permutación conḅ3
.Entonces podemos combinar las dos ramas con
œ?Ç
;œ?
significa "permutar dado este índice de permutación", yÇ
significa "el resultado de aplicar la línea de arriba", es decir, es lo que le dice a Jelly que ejecute ambas líneas por separado en la misma entrada.Lo que tenemos ahora son los dígitos del número original, en la base 36 (debido a
_J
), y en el orden original (debido a laœ?
), por lo que simplemente podemos hacer unaḅ36
conversión de la base 36 a un solo entero.Comentario
El tio! el enlace anterior usa 312699167 como el número para codificar. Este número en la base 36 es
[5, 6, 6, 8, 7, 35]
, y por lo tanto muestra todos los aspectos de la codificación: el 35 prueba el límite del rango 0-127 que tenemos; los duplicados 6 prueban la resolución de dígitos idénticos en la base original 36; y el hecho de que los dígitos están casi (pero no del todo) ordenados significa que el número de permutación es muy pequeño, lo que le da muchos menos dígitos que el número base 36 y, por lo tanto, muestra la necesidad de invertirlo antes de agregarlo al original.Es realmente conveniente cómo encajan todas las constantes aquí. 36 6 es solo lo suficientemente alto como para caber 2 31 , 3 6 es solo lo suficientemente alto como para caber 6 !, y (36 + 6) × 3 es solo lo suficientemente alto como para caber dentro de las 128 posibilidades que tenemos. (La última restricción aquí es la menos estricta, porque podríamos usar la indexación 0 en lugar de la indexación 1 para usar caracteres en el rango 0-2. Aún así, eso solo daría suficiente espacio para usar 37 como base en lugar de de 36.)
fuente
Gelatina , (
43 bytes +65 bytes) × longitud 8 =8064 puntosPruébalo en línea!
Gelatina , (
21 byte +43 bytes) × longitud 10 =6040 puntosPruébalo en línea!
Explicación
Solución 1
Esto está usando un algoritmo diferente de la mayoría de las otras respuestas. Comenzamos codificando el valor en hexadecimal (
b⁴
), como con las otras respuestas, luego tomamos una suma acumulativa (Ä
). Cada entrada dará claramente una salida diferente (ya que ambas operaciones son reversibles), y dado que la codificación hexadecimal contendrá como máximo 8 dígitos cuyos máximos son 7 (para el octavo último dígito) y 15 (para el último al séptimo) últimos dígitos), el número máximo en la lista de salida será 7+ (7 × 15) = 112, menos que los 127 requeridos por la pregunta. Además, la salida necesariamente estará ordenada, lo que nos permitirá revertir la combinación aleatoria.Para el decodificador, primero revertimos el shuffle con un sort (
Ṣ
); luego invierta la suma acumulativa, anteponiendo un cero (Ż
) y tomando la diferencia de pares consecutivos (I
); luego vuelva a convertir de hexadecimal (ḅ⁴
).Solución 2
La pregunta en realidad nos permite tomar la entrada como una lista de dígitos (presumiblemente decimales), para que podamos "engañar" simplemente eliminando la conversión de base; el número máximo utilizado en la salida será 2 + (9 × 9) = 83 (en realidad 82 porque 2999999999 está fuera de rango, por lo que la peor entrada posible es 1999999999). La codificación resultante es bastante terrible a medida que avanzan las codificaciones para este problema, pero tiene la ventaja de ser muy breve para generar, lo que supera la verbosidad de la codificación.
Esta respuesta se parece tanto a hacer trampa que no es mi solución principal para este problema, pero parece que vale la pena agregarla porque técnicamente cumple con las reglas y produce una mejor puntuación.
Comentario
Tengo algunos algoritmos en mente para obtener menos de la longitud 8, pero parece poco probable que pueda implementar un algoritmo de longitud 7 en ≤9 bytes (sin trampa) o ≤5 bytes (trampa), por lo que según la puntuación en la pregunta, esto Es probablemente la mejor manera de hacerlo. (De todos modos, podría intentar una solución para el desafío alternativo "minimizar la duración de la codificación", solo por diversión).
A diferencia de algunas de las soluciones, el uso de 16 como base aquí no es crítico; Hay muchos otros números que funcionarían para una solución de longitud 8 (por ejemplo, 18). Elegí 16 para la primera solución simplemente porque Jelly tiene una forma de 1 byte para representar eso, y otras bases viables tendrían que usar múltiples bytes del programa. Por supuesto, la segunda solución necesita usar 10 como base para explotar la escapatoria.
Gracias a @Dennis por señalar algunos nuevos comandos de Jelly que hicieron que este algoritmo fuera aún más difícil de escribir.
fuente
Ä
es la abreviatura de+\
,Ż
es la abreviatura de0;
.Lenguaje de programación de Shakespeare , 10 * (264 + 494) =
8650 79107580Codificador: 264 bytes
Pruébalo en línea!
Decodificador: 494
Pruébalo en línea!
Esto fue una cosa.
El codificador codifica cada dígito como el dígito más el índice del dígito multiplicado por doce. El decodificador almacena toda la entrada en la memoria del Ford y luego realiza un bucle sobre un contador, emitiendo y eliminando cada dígito por debajo del contador * 12 + 10.
Explicación:
Codificador
Descifrador
fuente
Python 2.7, 31 * (52 + 37) = 2759
Codificador (
6952 bytes):Decodificador (
4137 bytes):Almacena todos los bits distintos de cero en el número de entrada como valores ascii. El valor del carácter ascii almacena la posición del bit establecido. Por ejemplo, el valor 'a' significaría que el bit 97 está establecido.
Algunas mejoras, gracias a @ Delfad0r
Pruébalo en línea!
fuente
e =
y eld =
al principio: las funciones anónimas están perfectamente bien. Además, tenga en cuenta que la declaración del problema dice claramente que el codificador puede devolver una lista de enteros en lugar de caracteres, por lo que puede evitar la conversión de entero-> carácter-> entero. Además, puede usar enn&(1<<i)
lugar den&(1<<i)>0
y guardar 2 bytes. Finalmente, el límite superior parai
(127) es demasiado, 32 es suficiente y ahorra 1 byte.(52+37)*31=2759
que el más largo es cuando se establecen los 31 bits.lambda n:[chr(i)*(n&1<<i>0)for i in range(32)]
para guardar 6 bytes.Stax , puntaje 8 × (10 + 9) = 152
Codificador, 10 bytes
Ejecutar y depurarlo
El codificador emite la cadena en un orden creciente.
Decodificador, 9 bytes
Ejecutar y depurarlo
fuente
05AB1E , 8 longitud máxima * (8 + 7) bytes = 120
Codificador (8)
Pruébalo en línea!
Decodificador (7)
Pruébalo en línea!
Utiliza la misma técnica que wastl y Jonathan .
fuente
Python 3 , 8 * (45 + 38) = 664
Codificador (45 bytes):
Decodificador (38 bytes):
Pruébalo en línea!
fuente
lambda l:sum(x%16<<x//16*4for x in l)
funciona bien :)lambda n:[n>>4*i&15|i<<4for i in range(8)]
y 1 en el decodificador:lambda l:sum(x%16<<x//16*4for x in l)
para una puntuación total de 632JavaScript (ES6), 8 * (40 + 32) = 576
El codificador genera una matriz de0 0 a 8 enteros El decodificador toma el mismo formato que la entrada.
Codificador (40 bytes)
Decodificador (32 bytes)
Manifestación
Pruébalo en línea!
¿Cómo?
La entrada se divide en 8 bloques de 4 bits y cada bloque se codifica con 1 entre 16 caracteres posibles. El bit más significativo del último bloque nunca se establece.
fuente
Gelatina , (8 + 9) bytes * 8 longitud máxima = 136
Codificador (el pie de página formatea la lista como Python lo haría para mayor claridad)
Descifrador
Teóricamente es posible tener una longitud máxima de seis, ¿se puede hacer en 22 bytes o menos?
Es imposible con una longitud máxima de cinco desde∑i = 5i = 0( 127+i127) =321402081<231- 1
¿Cómo?
Ya que231- 1 es codificable como 8 dígitos hexadecimales (
7fffffff
o[7,15,15,15,15,15,15,15]
) entonces podemos agregar el índice basado en cero de cada dígito hexadecimal multiplicado por 16 para garantizar que dicha conversión esté siempre en orden ordenado mientras se mantienen incluso los valores más a la derecha (es decir[7,15,15,15,15,15,15,15] + [0,16,32,48,64,80,96,112] = [7,31,47,63,79,95,111,127]
). La decodificación está invirtiendo este mismo proceso.Codificador :
Decodificador :
fuente
Shakespeare Lenguaje de programación , 31 * (472 +
383379344) =265052638125296Puntuación anterior: 16909322 * (246 + 217) = 7829016086
Esto todavía es muy alto, pero es lo más bajo en lo que puedo pensar ahora.
Codificador:
Pruébalo en línea!
Descifrador:
Pruébalo en línea!
Básicamente, si la cadena contiene un carácter con el código ASCII (n + 1), se establece el enésimo dígito binario.
fuente
Python 3, (208 bytes + 200 bytes) * 6 de longitud = 2448
Pruébalo en línea! (contiene ambos, el byte adicional es la nueva línea entre ellos).
-4 bytes (puntaje -24) utilizando la lista vacía (que permitió que más cosas comenzaran en 0)
Codificador (208 bytes)
Decodificador (200 bytes)
Observaciones:
La combinación aleatoria se puede revertir sin pérdidas para listas estrictamente no crecientes (es decir, ordenadas).
Las listas numéricas estrictamente no crecientes de la misma longitud se pueden ordenar totalmente (como están en Python).
Podemos definir que las listas se ordenan primero por longitud para formar un orden total de todas las listas ordenadas.
Podemos formar una secuencia de indexable de estas listas si definimos que los valores sólo son válidos en una lista son números enteros de
0
al127
inclusivo (es decir, existe un número finito de listas válidos con longitudL
).Estrategia:
Codificador: dado un número
N
, encuentre la listaN
válida estrictamente no creciente.Decodificador: Dada una lista válida (barajada), ordénela y devuelva su índice en la secuencia de listas válidas.
Explicación de código común:
T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
Calcule el número
n
thd
-simplexPara
d=0
siempre1
Para
d=1
,n
(el número de puntos en una línea de puntos con longitudn
)para∑nortei = 1yo , (el número de puntos en un triángulo de puntos con longitud lateral
d=2
,n
)para∑nortej = 1∑ji = 1yo , (el número de puntos en un tetraedro de puntos con longitud lateral
d=3
,n
)Explicación del codificador:
def E(n,h=128):
d=l=0
,s=[]
n
es el número de entrada,h
es el "valor alto" (es decir, el número más alto permitido + 1),d
es la longitud que será la salida,s
es la salida,l
es el "valor bajo" (comenzando en 0, explicado más adelante)while n>=T(h,d):
`n-=T(h,d)
`d+=1
Hay listas de
T(h,d)
longitud válidasd
, y nuestro cálculo es más fácil sin
es un índice relativo a la lista[0]*d
(en el índice0
) en lugar de un índice real, por lo tanto, disminuya enn
consecuencia. Esto también ajustad
(la longitud) para que sea correcto para lo dadon
.for i in range(d):
Efectivamente: "para el
i+1
número th en la lista"Aquí es donde explicaré
l
, el "valor bajo"Después de que un número se ha puesto en la lista, no hay un número menor que el que se puede poner en la lista (para mantenerlo ordenado), así
l
es el último número que se agregó a la lista.while n>=T(h-l,d+~i):
`n-=T(h-l,d+~i)
`i+=1
Si
n
es demasiado grande para codificarse con unl
en este "dígito", ajústelo enn
consecuencia e incrementel
s+=[l]
Codifique
n
con unl
en este "dígito".Al principio, tenemos
h
opciones para qué "dígito" poner a continuación, pero una vez que ponemos un "dígito" (que se asigna al
), estamos limitados ah-l
opciones para el siguiente "dígito".Al principio había
T(h,d)
listas válidas, pero hemos agregado un "dígito"l
, disminuyendo el número de "dígitos" que quedand-1
y el número de "dígitos" próximos válidosh-l
, por lo que el número de listas válidas después de esto esT(h-l,d-1)
Explicación del decodificador:
def D(s):
,s.sort()
,l=0
,d=len(s)
s
es la lista de entrada (barajada), pors.sort()
lo que;l
es el "valor bajo" (h
el "valor alto" es literalmente128
s en el código para guardar bytes),n
es el número de salida,d
es la longitud.n=sum(T(128,D)for D in range(d))
Ajuste
n
al punto en la secuencia de[0]*length
for i in s:
Para cada dígito:
for j in range(l,i):
,n+=T(128-j,d-1)
Ajuste
n
al punto en la secuencia de[...prevdigits, thisdigit, 0...]
l=i
: Establezca el "valor bajo" en el dígito más reciented-=1
: Disminuye la longitud desde que usamos un dígitoreturn n
: Después den
haber sido ajustado para todos los dígitos, es el número correcto; devolverlo.Lo siento si esto no está claro, pero aquí está mi versión original de depuración no golfizada. , que no utiliza la lista vacía, por lo que es 1 de todos los números utilizados en esta versión
fuente
Ruby , (36 + 29 bytes) * 8, puntaje 520
Codificar:
Pruébalo en línea!
Descodificar:
Pruébalo en línea!
Cómo funciona:
El número se codifica utilizando fragmentos de 4 bits y un índice de 3 bits.
El decodificador toma la matriz de entrada y vuelve a colocar cada mordisco en su lugar.
fuente
Carbón , puntaje 10 * (10 + 15) = 250.
Utiliza decimal; la solución previa basada en base 16 obtuvo
328296264Puede generar caracteres no imprimibles. En particular, el carácter 10 es difícil de ingresar a Charcoal.
Codificador, 10 bytes:
Pruébalo en línea! El enlace es a la versión detallada del código.
Decodificador, 15 bytes:
Pruébalo en línea! El enlace es a la versión detallada del código.
Versión que usa una lista de enteros puntajes
360296 (base 16; el decimal sería 310):Codificador, 19 bytes:
Pruébalo en línea! El enlace es a la versión detallada del código.
Decodificador, 18 bytes:
Pruébalo en línea! El enlace es a la versión detallada del código.
Version usando caracteres imprimibles anota 360 (era
416384368 en base 16):Codificador, 19 bytes:
Pruébalo en línea! El enlace es a la versión detallada del código.
Decodificador, 17 bytes:
Pruébalo en línea! El enlace es a la versión detallada del código.
fuente
Brachylog , 17 + 18 bytes * 8 longitud = 280
Codificador:
Descifrador:
Se puede agregar una p al final del codificador sin ningún efecto. El decodificador se ejecuta colocando el resultado (aleatorio) como salida y obteniendo el número original en la entrada.
Si hubiera un predicado de suma acumulativa (implementado correctamente), el puntaje podría descender a 20
Pruébalo en línea!
fuente
05AB1E , puntuación: (2 + 2 bytes ) * 11 longitud máxima = 44
Codificador (2 bytes ):
Pruébalo en línea.
Decodificador (2 bytes ):
Pruébalo en línea.
La entrada del codificador y la salida del decodificador son una lista de dígitos.
La segunda respuesta de Jelly del puerto de @ ais523 .
Explicación:
Debido a que231- 1 tiene una longitud de 10 dígitos, la longitud máxima de la salida es 11.
.¥
antepone un cero a la salida, la longitud de la salida es la longitud de la entrada + 1. Desdefuente
Gol> <> , 8 * (14 + 13) = 216
Codificador Pruébelo en línea! , 14 bytes:
Decoder ¡ Pruébelo en línea! , 13 bytes:
Dado que esto puede generar caracteres ASCII no imprimibles, lo que hace que se entremezcle con el decodificador, ahora hay una versión que usa números en la salida / entrada:
Codificador Pruébelo en línea! , 14 bytes:
Decoder ¡ Pruébelo en línea! , 13 bytes:
Codificación:
The encoding works by breaking the given number into 8 x 4bit chunks. These chunks are then shifted right by 3 bit and the original location of the chunk is appended on the end as a number between 0 and 7. Thus the encoding looks like this:
fuente
Perl 6, 10 * (10 + 12) =
340220Encoder:
Decoder:
Try it online!
The encoder function zips each digit with the 0-index of the number. Then the encoder sorts the list of numbers and gets the modulo by 10, in other words the second digit of the number.
The total is 10, since that's the maximum length of 231-1.
fuente
Haskell, 10*(23+51) = 740
Here's a program that encodes, shuffles, decodes and validates values: Try it online!
Encoder, 23 bytes
Try it online!
Decoder, 51 bytes
Try it online!
Explanation
Since we're allowed to use input as decimal digits, we'll use that.. The encoder maps each digit that occurs to
10*index + digit
, note that alldigit
s will be in[0..9]
so we can reverse the above by usingdivMod
. After restoring the indices and the digits it's only a matter of sorting by the indices and getting rid of them.The solution is expected to work for values up to231−1=2147483647 which is 10 digits long, so the maximum code-point we get will be 9⋅9=81<128 . Also each digit will be converted to a "character", so we'll end up with a maximal length of 10.
fuente
Husk, 10*(7+8) = 150
Straight port of my Haskell solution only with the observation that10⋅9=90<128 (Husk's
N
is 1-based):Encoder, 7 bytes
Try it online!
Decoder, 8 bytes
Try it online!
fuente
APL (Dyalog Unicode),LE+LD=36;A=8→288 .
Try it online! (contains 5 extra bytes for the assignments and the newline).
Uses
⎕IO←0
How:
fuente
PHP, 8*(44+53) = 776
encoder, 44 bytes:
prints space separated list of integers. Run as pipe with
-nR
.maximum 8 bytes with 4 data bits (lower nibble) and 3 weight bits (upper nibble).
Simply put:
Put each hex digit in an own character and use the upper half of the byte to store the digit´s position.
example:
1457893891
(0x56e5b203
) will turn into0x03
,0x10
,0x22
,0x3b
,0x45
,0x5e
,0x66
,0x75
→
3 16 34 59 69 94 102 117
decoder, 53 bytes:
or
or
take integers from command line arguments. Run with
-nr
.Try them online.
fuente
Python 2, 10*(68+54) = 1220
Try it online!
EDIT: Thanks to Jo King for the pointers - not sure why I was offsetting by 32, in retrospect.
Encodes the position and value of each place as a single character, starting with
[space] (position 0, value 0)the NUL byte 0x0.Decodes by:
fuente
32
offset? Also,[-1]
could be%10
instead, in the right placeC (gcc), 10*112 = 1120
Try it online!
I have global variables, but they are not actually passing any info between two functions. Variable declaration for
c
is used in both functions saving me 2 bytes in code length.A version that uses printable ASCII only for a
35 byte penalty is here:Thanks @ceilingcat for 70 points improvements.
fuente