Códigos de barras de 4 estados
Muchos servicios postales (Royal Mail UK, Canada Post, US Mail, etc.) utilizan un código de barras de 4 estados para codificar información sobre su correo. Representado en ASCII, puede verse más o menos así:
El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El |
Un código de barras de 4 estados es una fila de barras. Cada barra se puede extender hacia arriba, hacia abajo o ambas, permitiendo 4 posibilidades. Esto significa que cada barra representa esencialmente una base de 4 dígitos:
El | El | Bar: | El | El | El | El | El | Dígito: 0 1 2 3
El problema con esta simbología es que cada código de barras es un código de barras válido y diferente al revés: cambiando drásticamente el significado si la orientación es incorrecta. Por lo tanto, normalmente se implementa una secuencia de inicio y parada para que el escáner pueda calcular de qué manera se supone que debe leerse.
Para el propósito de este desafío, utilizaremos la secuencia de inicio / parada especificada por Australia Post: cada código de barras comienza y termina con una 1 0
secuencia.
El reto
Su tarea es escribir un programa o función que, dado un entero positivo N
, lo convierta en un código de barras ASCII de 4 estados, donde cada barra (excepto las secuencias de inicio / parada) representa un dígito en la representación de base 4 N
.
Ejemplo:
Dado el número entero 19623
, tendríamos primero convertirlo a su representación de base 4, 10302213
.
Luego mapearíamos cada dígito a la barra correspondiente:
1 0 3 0 2 2 1 3 El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El |
Finalmente, agregaríamos las secuencias de inicio / parada:
Inicio fin: 1 0 1 0 El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El |
El código de barras resultante debe ser la salida del programa.
Reglas:
- La entrada será un número entero positivo, dentro del rango del tamaño entero estándar de su idioma.
- La salida:
- Puede ser una lista de líneas o una cadena que contiene nuevas líneas.
- Puede contener líneas / espacios iniciales o finales, siempre que la forma permanezca intacta.
- Debe mostrar el código de barras con el formato anterior: debe usar el carácter de tubería (
|
) y el carácter de espacio () al dibujar barras, y debe haber 1 espacio entre cada barra vertical.
- Este es el código de golf , por lo que gana el programa más corto (en bytes).
Casos de prueba
4095:
El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El |
4096:
El | El | El | El | El | El | El | El | El | El | El | El | El | El |
7313145:
El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El |
fuente
Respuestas:
Python 3 ,
1039996 bytesPruébalo en línea!
fuente
MATL ,
34302928 bytesPruébalo en línea!
Explicación
fuente
Jalea ,
1615 bytesPruébalo en línea!
Cómo funciona
fuente
.......
pero cada punto representa un byte diferente.Jalea , 19 bytes
Pruébalo en línea!
-1 gracias al Sr. Xcoder .
fuente
Octava ,
78 77 75 74 7069 bytesPruébalo en línea!
A diferencia del enfoque original, este utiliza una tabla de búsqueda simple para mapear los valores de base 4 en su equivalente binario. La tabla de búsqueda también agrega el espacio entre cada barra al agregar un cero entre cada número (que se asigna a una barra de todos los espacios).
La tabla de búsqueda se asigna directamente a barras como:
La conversión de binario a
|
yahora se realiza indexando en una cadena de esos dos caracteres, básicamente el mismo principio que la tabla de búsqueda para la conversión binaria.
* Guardado 1 byte, gracias @LuisMendo
Original:
Pruébalo en línea!
Función anónima que devuelve el código de barras como una cadena.
Esto se basa en el hecho de que si sumamos 4 a los dígitos de base4, entonces podemos representar barra / espacio por el número convertido a binario con los bits 1 y 2 intercambiados:
La parte difícil desde una perspectiva de golf es agregar los espacios entre las barras y convertir de
0/1
a'|'/' '
.fuente
JavaScript (ES6),
898783 bytesCasos de prueba
Mostrar fragmento de código
¿Cómo?
Nota : en la versión siguiente, los literales de plantilla se han reemplazado por cadenas estándar para que el código se pueda sangrar correctamente.
fuente
R ,
154109bytesPruébalo en línea!
Ahorró un montón de bytes indexando y usando en
cat
lugar de construir una matriz y usandowrite
, así como 6 de una conversión ligeramente diferente a la base 4. Imprime con un espacio inicial en cada fila y sin líneas nuevas.La indexación se lleva a cabo utilizando algo de aritmética modular, no muy diferente de otras respuestas, pero dado que R usa indización basada en 1, la aritmética es algo diferente.
Explicación:
fuente
Carbón de leña , 50 bytes
Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:
Ingrese un número.
Empuje la secuencia de detención a la lista vacía predefinida.
Si el número es positivo,
aplica repetidamente divmod para convertirlo a la base 4 invertida,
de lo contrario solo empújalo.
Empuje la secuencia de inicio a la lista.
Mapa sobre tres cuerdas. Cada cadena representa la traducción del código de barras para los dígitos
0123
de cada fila.Asigne los dígitos (invertidos nuevamente en el orden habitual), conviértalos en barras o espacios usando la traducción, luego combine los resultados en tres cadenas que luego se imprimen implícitamente en líneas separadas.
fuente
Japt ,
3231 bytes¡Pruébelo en línea!
Todavía no estoy satisfecho con esto, pero es un comienzo ...
Explicación
fuente
Haskell ,
9190 bytesPruébalo en línea! Devuelve una lista de líneas.
La misma alternativa de conteo de bytes para la primera línea:
fuente
J ,
57 4947 bytes10 bytes gracias a FrownyFrog!
Cómo funciona:
1 0,4&#.inv,1,0:
- convierte el número en una lista de dígitos de base 4, agrega 1 0 al principio y al final de la lista((#:2 6 3 7){' |')
- tabla de búsqueda para el cifrado, 0 binario corresponde al espacio, 1 a '|'{~
- encripta los 4 dígitos base seleccionando una cadena de la tabla de búsqueda anterior (argumento invertido)|:
- transpone la matriz resultante de 3 columnas a 3 filas[:
- tapa el tenedor,.2{."0
- pone espacios entre las barrasPruébalo en línea!
fuente
APL + WIN, 63 bytes
Explicación:
fuente
Python 2 ,
116114 bytes-2 bytes gracias a notjagan
Pruébalo en línea!
fuente
05AB1E , 19 bytes
Pruébalo en línea!
Este es un medio puerto del enfoque de Dennis, que es solo un byte más corto que el método que usé antes (con el que estoy bastante satisfecho):
05AB1E , 20 bytes
Pruébalo en línea!
¿Cómo funciona?
Le pregunté a Adnan (el creador de 05AB1E) acerca de la cuadrícula en el chat , y me ayudaron a ahorrar 2 bytes, señalando una característica de 05AB1E: al unir listas multidimensionales por nuevas líneas, las listas internas se unen usando espacios también , entonces
ðý
es innecesario.fuente
APL (Dyalog Classic) , 33 bytes
Pruébalo en línea!
fuente
2⊥⍣¯1
¿cómo obtendrías una lista binaria?2⊥⍣¯1
es el inverso ("anverso"?) De "dos decodificaciones". Se codifica en binario con tantos bits como sea necesario.J ,
42 4039 bytesAfeitado 2 bytes gracias a Dennis. 1 byte gracias a ngn.
Pruébalo en línea!
Cómo funciona
fuente
JavaScript (ES6) 79 bytes
Utiliza .toString para convertir el número a base 4, y luego el trabajo de caso con cada línea y OR a nivel de bits para construir la salida línea por línea. Emite una lista de líneas.
fuente
`10${n.toString(4)}10`
:)Bash + coreutils,
7167 bytesPruébalo en línea!
Explicación
El
dc
bit se convierte en base 4, anteponiendo y agregando un4
(se convierte10
en la salida) y usandon
para mantener todo en una línea.El resto sucede en
sed
:fuente
x
los espacios de espera / patrón para modificarlos y luego hacers
todo de una vez, y nada terminó más corto.Retina , 83 bytes
Pruébalo en línea! El enlace incluye los casos de prueba más rápidos. Explicación:
Convierte a unario.
Convierte a base 4 como números unarios separados por
;
s.Anteponer la secuencia de inicio.
Agregue a
;
, convirtiéndolo en un terminador de dígitos en lugar de un separador, y la secuencia de parada.Convierte a decimal, pero suma 1 a cada dígito.
Triplicarlo.
En la primera fila,
1
S y3
s (que representan0
s y2
s) se convierten en espacios.En la última fila,
1
S y2
s (que representan0
s y1
s) se convierten en espacios.Todos los demás dígitos se convierten en barras.
fuente
Pip ,
3331292726 bytes25 bytes de código, +1 para
-S
bandera.Pruébalo en línea!
Explicación
Observamos un patrón en los cuatro tipos de barras:
Asi que:
fuente
SOGL V0.12 , 28 bytes
Pruébalo aquí!
fuente
C (gcc) , 176 bytes
Pruébalo en línea!
Ligeramente menos terriblemente formateado (menos golfizado):
Explicación
Primero, considere el siguiente código para leer un número entero y generar la versión base 4:
Esto utiliza la recursividad de cola para invertir el orden de la salida. Cada paso recursivo cambia de bit por 2 (corta los últimos 2 bits y divide por 4). Emite el resultado enmascarado con 3 (0b11), que solo muestra los dos últimos bits, que es la última base de 4 dígitos.
La llamada a la función se incluye
printf
como argumento final (no se imprime, pero se evalúa) para evitar la necesidad de utilizar {} (+2 bytes) para agrupar laprintf
llamada a la función.La solución aquí extiende este código de base 4. Primero, m se define como n, pero tal que en la base 4 tendrá 10 antepuestos y anexados. Luego imprimimos m.
En la impresión de la base 4 regularmente, usamos una máscara de bits de 3 para obtener el dígito. En el código de correo, la línea superior es el bit de orden inferior de ese dígito (una máscara de bits de 1) y la línea inferior es el bit de orden superior (una máscara de bits de 2). En consecuencia, el
r
def(n,r)
es la máscara de bits - nuestros principales llamadas a funcionesf(m,1)
para la primera línea yf(m,2)
para la última línea.Para que la línea media funcione (siempre imprima "|"), agregamos
||!r
al condicional: si r es 0, siempre se evaluará como verdadero e imprimirá un "|". Luego llamamosf(m,0)
a la línea media.Finalmente, queremos que las nuevas líneas se comporten. Incluir un extra
printf
es costoso en lo que respecta a los bytes del código fuente, por lo que en su lugar agregamos otro especificador% c al existenteprintf
.n?32:10
imprime una nueva línea si n es 0 (falso) y un espacio en caso contrario. 32 y 10 se utilizan en lugar de '\ n' y '' para guardar bytes.fuente
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 común, 191 bytes
Pruébalo en línea!
fuente
PHP, 99 + 1 bytes
requiere PHP> = 5.5 para la indexación de cadenas literales y <7.1 para que la indexación no produzca una advertencia.
Ejecutar como tubería con
-nR
o probarlo en línea .Inserte una nueva línea más para obtener una línea final.
fuente
Python 2,
142126bytesMuchas gracias a los ovs!
Traté de no copiar los métodos de las otras respuestas y ... qué asco.
fuente
C # (.NET Core) , 160 bytes
Pruébalo en línea!
Estoy seguro de que me he perdido algunas mejoras.
DeGolfed
t<51 & y != 1 & t-(y>>1) != 49
comprueba que el carácter no sea '3', no la segunda fila, y luego algo de magia binaria para ver si la primera o tercera fila debe contener el espacio.fuente
Zsh ,
156154151133 bytesPruébalo en línea!
Toma entrada de base 10 de la var
$x
fuente
Japt , 42 bytes
Pruébalo en línea!
fuente
Pyth , 32 bytes
Pruébalo aquí!
fuente
C, 120 bytes
Lamentablemente solo funciona en Windows, ya que
itoa
es demasiado conveniente para ser estándar.fuente