Il codice Hamming (7,4) risale al 1950. All'epoca Richard Hamming lavorava come matematico presso i Bell Labs. Ogni venerdì Hamming imposta le macchine calcolatrici per eseguire una serie di calcoli e raccoglie i risultati il lunedì successivo. Utilizzando i controlli di parità, queste macchine sono state in grado di rilevare errori durante il calcolo. Frustrato, poiché ha ricevuto messaggi di errore troppo spesso, Hamming ha deciso di migliorare il rilevamento degli errori e ha scoperto i famosi codici Hamming.
Mechanics of the Hamming (7,4)
L'obiettivo dei codici Hamming è quello di creare un insieme di bit di parità che si sovrappongono in modo tale che sia possibile rilevare e correggere un errore a bit singolo (un bit viene capovolto) in un bit di dati o un bit di parità. Solo se si verificano più errori, il codice Hamming non riesce a recuperare i dati originali. Potrebbe non notare affatto un errore o addirittura correggerlo erroneamente. Pertanto in questa sfida ci occuperemo solo di errori a bit singolo.
Come esempio dei codici di Hamming, vedremo il codice di Hamming (7,4). Oltre a 4 bit di dati d1, d2, d3, d4
utilizza 3 bit di parità p1, p2, p3
, che vengono calcolati utilizzando le seguenti equazioni:
p1 = (d1 + d2 + d4) % 2
p2 = (d1 + d3 + d4) % 2
p3 = (d2 + d3 + d4) % 2
La parola in codice risultante (dati + bit di parità) è nel formato p1 p2 d1 p3 d2 d3 d4
.
Il rilevamento di un errore funziona nel modo seguente. Si ricalcola i bit di parità e si controlla se corrispondono ai bit di parità ricevuti. Nella tabella seguente puoi vedere che ogni varietà di un errore a bit singolo produce una corrispondenza diversa dei bit di parità. Pertanto, ogni errore a singolo bit può essere localizzato e corretto.
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
Esempio
Lascia che i tuoi dati siano 1011
. I bit di parità sono p1 = 1 + 0 + 1 = 0
, p2 = 1 + 1 + 1 = 1
e p3 = 0 + 1 + 1 = 0
. Combina i dati e i bit di parità e otterrai la parola chiave 0110011
.
data bits | 1 011
parity bits | 01 0
--------------------
codeword | 0110011
Diciamo durante una trasmissione o un calcolo il sesto bit (= terzo bit di dati) capovolge. Tu ricevi la parola 0110001
. I presunti dati ricevuti sono 1001
. Si calcola nuovamente i bit di parità p1 = 1 + 0 + 1 = 0
, p2 = 1 + 0 + 1 = 0
, p3 = 0 + 0 + 1 = 1
. p1
Corrisponde solo ai bit di parità della parola chiave 0110001
. Pertanto si è verificato un errore. Guardando la tabella sopra, ci dice che si è verificato l'errore d3
e puoi recuperare i dati originali 1011
.
Sfida:
Scrivi una funzione o un programma che riceve una parola (7 bit), uno dei bit potrebbe essere errato e recupera i dati originali. Il formato di input (tramite STDIN, argomento della riga di comando, argomento prompt o funzione) può essere una stringa "0110001"
, un elenco o un array [0, 1, 1, 0, 0, 0, 1]
o un numero intero in MSB 0b0110001 = 49
. Come descritto sopra, l'ordine dell'input è p1 p2 d1 p3 d2 d3 d4
. L'output (tramite valore di ritorno o STDOUT) deve essere dello stesso formato, ma nell'ordine d1 d2 d3 d4
. Restituisce / emette solo i 4 bit di dati.
Questo è code-golf. Pertanto vince il codice più breve.
Casi 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]
base due, indica la posizione del bit errato nella parola. (Basato sulla tabella nella domanda.) Questo probabilmente sarà utile per alcuni algoritmi.