El código Hamming (7,4) se remonta a 1950. En aquel entonces, Richard Hamming trabajó como matemático en los Laboratorios Bell. Todos los viernes, Hamming configuró las máquinas de cálculo para realizar una serie de cálculos y recolectó los resultados el lunes siguiente. Mediante el uso de verificaciones de paridad, estas máquinas pudieron detectar errores durante el cálculo. Frustrado, porque recibió mensajes de error con demasiada frecuencia, Hamming decidió mejorar la detección de errores y descubrió los famosos códigos de Hamming.
Mecánica del Hamming (7,4)
El objetivo de los códigos de Hamming es crear un conjunto de bits de paridad que se superpongan de tal manera que se pueda detectar y corregir un error de un solo bit (se invierte un bit) en un bit de datos o un bit de paridad. Solo si se producen varios errores, el código de Hamming no puede recuperar los datos originales. Es posible que no note ningún error, o incluso que lo corrija falsamente. Por lo tanto, en este desafío solo trataremos con errores de un solo bit.
Como ejemplo de los códigos de Hamming, veremos el código de Hamming (7,4). Además de 4 bits de datos d1, d2, d3, d4
, utiliza 3 bits de paridad p1, p2, p3
, que se calculan utilizando las siguientes ecuaciones:
p1 = (d1 + d2 + d4) % 2
p2 = (d1 + d3 + d4) % 2
p3 = (d2 + d3 + d4) % 2
La palabra de código resultante (datos + bits de paridad) tiene la forma p1 p2 d1 p3 d2 d3 d4
.
La detección de un error funciona de la siguiente manera. Vuelve a calcular los bits de paridad y comprueba si coinciden con los bits de paridad recibidos. En la siguiente tabla puede ver que cada variedad de un error de un solo bit produce una coincidencia diferente de los bits de paridad. Por lo tanto, cada error de un solo bit puede ser localizado y corregido.
error in bit | p1 | p2 | d1 | p3 | d2 | d3 | d4 | no error
-------------|---------------------------------------------
p1 matches | no | yes| no | yes| no | yes| no | yes
p2 matches | yes| no | no | yes| yes| no | no | yes
p3 matches | yes| yes| yes| no | no | no | no | yes
Ejemplo
Deja que tus datos sean 1011
. Los bits de paridad son p1 = 1 + 0 + 1 = 0
, p2 = 1 + 1 + 1 = 1
y p3 = 0 + 1 + 1 = 0
. Combine los datos y los bits de paridad y obtendrá la palabra de código 0110011
.
data bits | 1 011
parity bits | 01 0
--------------------
codeword | 0110011
Digamos que durante una transmisión o un cálculo, el sexto bit (= tercer bit de datos) se voltea. Recibes la palabra 0110001
. Los supuestos datos recibidos son 1001
. Se calculan los bits de paridad de nuevo p1 = 1 + 0 + 1 = 0
, p2 = 1 + 0 + 1 = 0
, p3 = 0 + 0 + 1 = 1
. Solo p1
coincide con los bits de paridad de la palabra de código 0110001
. Por lo tanto, se produjo un error. Mirando la tabla anterior, nos dice que ocurrió el error d3
y puede recuperar los datos originales 1011
.
Desafío:
Escriba una función o un programa que reciba una palabra (7 bits), uno de los bits podría estar equivocado y recupere los datos originales. El formato de entrada (a través de STDIN, argumento de línea de comando, argumento de solicitud o función) puede ser una cadena "0110001"
, una lista o una matriz [0, 1, 1, 0, 0, 0, 1]
o un entero en MSB 0b0110001 = 49
. Como se describió anteriormente, el orden de la entrada es p1 p2 d1 p3 d2 d3 d4
. La salida (a través del valor de retorno o STDOUT) debe ser del mismo formato, pero en el orden d1 d2 d3 d4
. Solo devuelve / emite los 4 bits de datos.
Este es el código de golf. Por lo tanto, el código más corto gana.
Casos de prueba:
1110000 -> 1000 # no error
1100000 -> 1000 # error at 1st data bit
1111011 -> 1111 # error at 2nd data bit
0110001 -> 1011 # error at 3rd data bit (example)
1011011 -> 1010 # error at 4th data bit
0101001 -> 0001 # error at 1st parity bit
1010000 -> 1000 # error at 2nd parity bit
0100010 -> 0010 # error at 3rd parity bit
[is_p3_wrong][is_p2_wrong][is_p1_wrong]
base dos, le da la posición del bit incorrecto en la palabra. (Basado en la tabla de la pregunta). Esto probablemente será útil para algunos algoritmos.