Kod Hamminga (7,4) sięga 1950 roku. Wtedy Richard Hamming pracował jako matematyk w Bell Labs. W każdy piątek Hamming ustawiał maszyny liczące do wykonywania serii obliczeń i zbierał wyniki w następny poniedziałek. Za pomocą kontroli parzystości maszyny te były w stanie wykryć błędy podczas obliczeń. Sfrustrowany, ponieważ zbyt często otrzymywał komunikaty o błędach, Hamming postanowił poprawić wykrywanie błędów i odkrył słynne kody Hamminga.
Mechanika Hamminga (7,4)
Celem kodów Hamminga jest utworzenie zestawu bitów parzystości, które nakładają się na siebie, tak że błąd jednego bitu (jeden bit jest odwracany) w bicie danych lub bit parzystości może zostać wykryty i skorygowany. Tylko w przypadku wystąpienia wielu błędów kod Hamminga nie może odzyskać oryginalnych danych. Może w ogóle nie zauważyć błędu, a nawet poprawić go fałszywie. Dlatego w tym wyzwaniu zajmiemy się tylko błędami jednobitowymi.
Jako przykład kodów Hamminga przyjrzymy się kodowi Hamminga (7,4). Oprócz 4 bitów danych d1, d2, d3, d4
wykorzystuje 3 bity parzystości p1, p2, p3
, które są obliczane przy użyciu następujących równań:
p1 = (d1 + d2 + d4) % 2
p2 = (d1 + d3 + d4) % 2
p3 = (d2 + d3 + d4) % 2
Wynikowe słowo kodowe (dane + bity parzystości) ma postać p1 p2 d1 p3 d2 d3 d4
.
Wykrywanie błędu działa w następujący sposób. Ponownie oblicz bity parzystości i sprawdź, czy pasują one do odebranych bitów parzystości. W poniższej tabeli widać, że każda odmiana błędu jednobitowego daje inne dopasowanie bitów parzystości. Dlatego każdy błąd jednobitowy można zlokalizować i poprawić.
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
Przykład
Niech twoje dane będą 1011
. Bity kontroli parzystości są p1 = 1 + 0 + 1 = 0
, p2 = 1 + 1 + 1 = 1
i p3 = 0 + 1 + 1 = 0
. Połącz dane i bity parzystości, a otrzymasz słowo kodowe 0110011
.
data bits | 1 011
parity bits | 01 0
--------------------
codeword | 0110011
Powiedzmy, że podczas transmisji lub obliczeń szósty bit (= trzeci bit danych) odwraca się. Otrzymujesz słowo 0110001
. Domniemane otrzymane dane to 1001
. Ponownie obliczyć bity parzystości p1 = 1 + 0 + 1 = 0
, p2 = 1 + 0 + 1 = 0
, p3 = 0 + 0 + 1 = 1
. p1
Dopasowuje tylko bity parzystości słowa kodowego 0110001
. Dlatego wystąpił błąd. Patrząc na powyższą tabelę, mówi nam, że wystąpił błąd d3
i możesz odzyskać oryginalne dane 1011
.
Wyzwanie:
Napisz funkcję lub program, który odbiera słowo (7 bitów), jeden z bitów może być nieprawidłowy i odzyskuje oryginalne dane. Format wejściowy (przez STDIN, argument wiersza poleceń, monit lub argument funkcji) może być ciągiem "0110001"
, listą, tablicą [0, 1, 1, 0, 0, 0, 1]
lub liczbą całkowitą w MSB 0b0110001 = 49
. Jak opisano powyżej, kolejność wprowadzania jest następująca p1 p2 d1 p3 d2 d3 d4
. Dane wyjściowe (poprzez wartość zwracaną lub STDOUT) muszą mieć ten sam format, ale w kolejności d1 d2 d3 d4
. Zwracaj / wysyłaj tylko 4 bity danych.
To jest golf golfowy. Dlatego wygrywa najkrótszy kod.
Przypadki testowe:
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]
pod uwagę podstawę drugą, to podaje pozycję niepoprawnego bitu w słowie. (Na podstawie tabeli w pytaniu.) Prawdopodobnie będzie to przydatne w przypadku niektórych algorytmów.