Le code Hamming (7,4) remonte à 1950. À l'époque, Richard Hamming travaillait comme mathématicien aux Bell Labs. Chaque vendredi, Hamming réglait les machines à calculer pour effectuer une série de calculs et collectait les résultats le lundi suivant. Grâce à des contrôles de parité, ces machines ont pu détecter des erreurs lors du calcul. Frustré, parce qu'il recevait trop souvent des messages d'erreur, Hamming a décidé d'améliorer la détection des erreurs et a découvert les fameux codes Hamming.
Mécanique du Hamming (7,4)
Le but des codes de Hamming est de créer un ensemble de bits de parité qui se chevauchent de telle sorte qu'une erreur sur un bit (un bit est inversé) dans un bit de données ou un bit de parité puisse être détectée et corrigée. Ce n'est qu'en cas d'erreurs multiples que le code Hamming ne parvient pas à récupérer les données d'origine. Il peut ne pas remarquer du tout d'erreur, ni même le corriger faussement. Par conséquent, dans ce défi, nous ne traiterons que des erreurs mono-bit.
Comme exemple des codes de Hamming, nous examinerons le code de Hamming (7,4). En plus de 4 bits de données, d1, d2, d3, d4
il utilise 3 bits de parité p1, p2, p3
, qui sont calculés à l'aide des équations suivantes:
p1 = (d1 + d2 + d4) % 2
p2 = (d1 + d3 + d4) % 2
p3 = (d2 + d3 + d4) % 2
Le mot de code résultant (données + bits de parité) est de la forme p1 p2 d1 p3 d2 d3 d4
.
La détection d'une erreur fonctionne de la manière suivante. Vous recalculez les bits de parité et vérifiez s'ils correspondent aux bits de parité reçus. Dans le tableau suivant, vous pouvez voir que chaque variété d'erreur sur un seul bit produit une correspondance différente des bits de parité. Par conséquent, chaque erreur sur un seul bit peut être localisée et corrigée.
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
Exemple
Laissez vos données être 1011
. Les bits de parité sont p1 = 1 + 0 + 1 = 0
, p2 = 1 + 1 + 1 = 1
et p3 = 0 + 1 + 1 = 0
. Combinez les données et les bits de parité et vous obtenez le mot de code 0110011
.
data bits | 1 011
parity bits | 01 0
--------------------
codeword | 0110011
Disons que lors d'une transmission ou d'un calcul le 6ème bit (= 3ème bit de données) bascule. Vous recevez le mot 0110001
. Les prétendues données reçues sont 1001
. On calcule à nouveau les bits de parité p1 = 1 + 0 + 1 = 0
, p2 = 1 + 0 + 1 = 0
, p3 = 0 + 0 + 1 = 1
. Correspond uniquement p1
aux bits de parité du mot de code 0110001
. Une erreur s'est donc produite. En regardant le tableau ci-dessus, nous indique que l'erreur s'est produite dans d3
et vous pouvez récupérer les données d'origine 1011
.
Défi:
Écrivez une fonction ou un programme qui reçoit un mot (7 bits), l'un des bits peut être incorrect et récupérez les données d'origine. Le format d'entrée (via STDIN, argument de ligne de commande, invite ou fonction) peut être une chaîne "0110001"
, une liste ou un tableau [0, 1, 1, 0, 0, 0, 1]
ou un entier dans MSB 0b0110001 = 49
. Comme décrit ci-dessus, l'ordre de l'entrée est p1 p2 d1 p3 d2 d3 d4
. La sortie (via la valeur de retour ou STDOUT) doit être du même format, mais dans l'ordre d1 d2 d3 d4
. Renvoie / émet uniquement les 4 bits de données.
C'est du code-golf. Par conséquent, le code le plus court l'emporte.
Cas de test:
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]
en base deux, cela donne la position du bit incorrect dans le mot. (Basé sur le tableau de la question.) Cela sera probablement utile pour certains algorithmes.