La codificación Manchester es un protocolo de telecomunicaciones utilizado en las comunicaciones de radio que garantiza las transiciones de bits a intervalos regulares para que un receptor pueda recuperar la frecuencia de reloj de los datos en sí. Duplica la tasa de bits, pero es barata y fácil de implementar. Es ampliamente utilizado por los operadores de radioaficionados.
El concepto es muy simple: a nivel de hardware, el reloj y las líneas de datos simplemente se combinan en XOR. En el software, esto se representa como la conversión de un flujo de bits de entrada en un flujo de salida de doble velocidad, con cada entrada '1' traducida a '01' y cada entrada '0' traducida a '10'.
Este es un problema fácil, pero está abierto a muchas implementaciones debido a su naturaleza de flujo de bits. Es decir, la codificación es conceptualmente un proceso bit a bit en lugar de un proceso byte a byte. Entonces, todos estamos de acuerdo en la endianidad, los bits menos significativos de la entrada se convierten en el byte menos significativo de la salida.
¡Tiempo de golf! Escriba una función que, dada una matriz arbitraria de bytes de longitud, devuelva una matriz de esos datos codificados por Manchester.
La entrada y la salida deben considerarse little-endian, el byte menos significativo primero y el BIT menos significativo primero en el flujo de bits.
Dibujo de flujo de bits ASCII :
bit # 5 4 3 2 1 0 5 4 3 2 1 0
IN ------- 1 0 1 0 1 1 ---> [manchester encoder] --- 01 10 01 10 01 01 ----> OUT
Ejemplos :
Example 1 (hex):
LSB MSB <-- least sig BYTE first
IN : [0x10, 0x02]
OUT: [0xAA, 0xA9, 0xA6, 0xAA]
Example 1 (binary):
msb lsb msb lsb <-- translated hex, so msb first
BIN: [00010000, 00000010] <-- least sig NIBBLE...
BIN: [10101010, 10101001, 10100110, 10101010] <-- becomes least sig BYTE
LSB MSB
Example 2
IN : [0xFF, 0x00, 0xAA, 0x55]
OUT: [0x55, 0x55, 0xAA, 0xAA, 0x66, 0x66, 0x99, 0x99]
Example 3
IN : [0x12, 0x34, 0x56, 0x78, 0x90]
OUT: [0xA6, 0xA9, 0x9A, 0xA5, 0x96, 0x99, 0x6A, 0x95, 0xAA, 0x69]
Example 4
IN : [0x01, 0x02, 0x03, 0xF1, 0xF2, 0xF3]
OUT: [0xA9, 0xAA, 0xA6, 0xAA, 0xA5, 0xAA, 0xA9, 0x55, 0xA6, 0x55, 0xA5, 0x55]
reglas :
- La solución solo requiere un algoritmo para convertir la entrada en salida.
- La adquisición de entrada y salida de impresión NO son una parte necesaria de la solución, pero pueden incluirse. Le recomendamos que proporcione su código de prueba / impresión si no está incluido en su solución.
- La entrada es una matriz de bytes de 8 bits (lo que sea que eso signifique en el idioma que elija), NO una cadena de texto. Puede usar cadenas como formato de almacenamiento si es conveniente en su idioma, pero se deben admitir caracteres no imprimibles (es decir, 0xFF). La entrada también puede tomar una longitud si es necesario.
La memoria para la salida debe ser asignada por su rutina, no proporcionada.editar: requisito innecesario- La salida también es una matriz de bytes de 8 bits, y una longitud si es necesario.
- Debe admitir al menos 16 KB de entrada
- El rendimiento no debe ser demasiado horrible: <10 segundos por 16 KB
- Byte menos significativo primero en la memoria.
Desafío de canal lateral :
- ¡Desafíe la respuesta de otro usuario demostrando que su código es más rápido, más eficiente en memoria o produce un binario más pequeño!
Respuestas:
GolfScript 28 caracteres
Versión equivalente sin optimización ofuscante:
El código acepta la entrada como una matriz de enteros y devuelve lo mismo.
Para cada número en la matriz, el número se convierte a la forma de la matriz de base 2, luego se convierte de nuevo en un número como si fuera la base 4, esto tiene el efecto de espaciar los bits con un 0 entre cada uno. 43691 luego se resta del número, y el resultado es binario invertido, esto es equivalente a restar el número de 43690 (43690 = 0b1010101010101010). El número se divide en dos partes al convertirlo en una matriz base 256, la matriz se descompone y se invierte el orden de los dos números resultantes.
Entrada de ejemplo:
Salida de ejemplo:
fuente
{2{base}:|~4|43691-~256|~p p}%
c - 224 caracteres
Creo que esto es funcional, incluida la asignación de requisitos de memoria desde que cayó.
La parte funcional del código es un bucle sobre los bits de cada carácter, observando que ((bit + 1) exclusivo-o 3) es el par de bits de salida, y aplica mucha lógica de desplazamiento y enmascaramiento para alinear todo.
Como es habitual en c, funciona en los datos como caracteres. El andamio de prueba no aceptará 0 bytes (porque c los trata como un final de cadena), pero el código de trabajo no tiene esa limitación.
Se podría jugar un poco más al copiar el trabajo de conversión de bytes en línea.
Prueba de funcionamiento (con andamio de prueba mejorado):
Comentado, menos dependiente de la máquina y con andamio de prueba
fuente
J, 36
Esquema de explicación (Ver vocabulario J para referencia):
,@:(3 :'...'"0)
aplica el ... a cada entrada "byte" como y, dando como resultado dos bytes (enteros) cada uno. El resultado es aplanado por,
.y#:~8#2
es equivalente a2 2 2 2 2 2 2 2 #: y
, o vector de los 8 dígitos de base 2 menos significativos de y.4|.
intercambia el frente y la parte posterior 4 bits girando 4 posiciones.(,.~-.)
es equivalente3 :'(-. y) ,. y'
o no al argumento 'cosido' al argumento (tomando forma 8 2).#.2 8$,
aplana el resultado dando el flujo de bits, da nueva forma a 2 filas de 8 y convierte desde la base 2.Ejemplo de uso (J, interactivo):
Información de velocidad (J, interactiva):
El tiempo medio para 16kb es de menos de .25s, Intel Core Duo 1.83Ghz o similar.
fuente
Haskell, 76 personajes
Pruebas de funcionamiento:
El rendimiento está dentro de las especificaciones. a 1MB en ~ 1.2s en mi laptop antigua. Sufre porque la entrada se convierte ay desde una lista, en lugar de procesarse como a
ByteArray
.La fuente, 2040-Manchester.hs , incluye el código, las pruebas y la función principal para un filtro de línea de comando.
fuente
OCaml + Batteries,
138117caracteresPruebas:
Con
Los resultados son:
Como punto de referencia, con:
Yo obtengo:
en mi MacBook
fuente
Python, 87 caracteres
M
es la función solicitada en el problema. LlamaN
a cada nybble y divide todo en una lista.genera
fuente
APL (Dyalog Extended) , 22 bytes
Pruébalo en línea!
Puerto de la respuesta GolfScript.
fuente
C, 164 bytes
Toma una serie de bytes hexadecimales y los convierte a flujo binario de Manchester.
Prueba:
Salida:
Generador de conjunto de datos de prueba de 16 kb:
test_data.c:
Contrarreloj de núcleo 1.6G i5dual:
fuente
PHP, 156 bytes
Dada la entrada
[0, 1, 2, 3, 4, 5]
, devuelve:Codifica 16 KiB de datos en 0.015 segundos y 1 MiB de datos en aproximadamente 0.9 segundos.
El código no protegido, otra implementación (más larga y aproximadamente dos veces más lenta) y los casos de prueba se pueden encontrar en mi página de soluciones de código de golf en Github.
fuente