Код Хеммінга (7,4) починається з 1950 року. Тоді Річард Хеммінг працював математиком у Bell Labs. Щоп’ятниці Хеммінг встановлював обчислювальні машини, щоб виконати ряд розрахунків, і збирав результати наступного понеділка. За допомогою перевірок парності ці машини змогли виявити помилки під час обчислення. Розчарований, оскільки надто часто отримував повідомлення про помилки, Хеммінг вирішив покращити виявлення помилок і виявив відомі коди Хеммінга.
Механіка Хеммінга (7,4)
Мета кодів Хеммінга - створити набір бітів парності, які перекриваються таким чином, щоб однобітна помилка (один біт перевернута) у біті даних або біт парності можна було виявити та виправити. Тільки якщо трапляються кілька помилок, код Хеммінга не вдається відновити вихідні дані. Він може взагалі не помітити помилку або навіть помилково виправити її. Тому в цьому виклику ми будемо мати справу лише з однорозрядними помилками.
Як приклад кодів Хеммінга, ми розглянемо код Хеммінга (7,4). Додатково до 4 біт даних d1, d2, d3, d4
він використовує 3 біти парності p1, p2, p3
, які обчислюються за допомогою наступних рівнянь:
p1 = (d1 + d2 + d4) % 2
p2 = (d1 + d3 + d4) % 2
p3 = (d2 + d3 + d4) % 2
Отримане кодове слово (дані + біти парності) має форму p1 p2 d1 p3 d2 d3 d4
.
Виявлення помилки працює наступним чином. Ви перераховуєте біти парності та перевіряєте, чи відповідають вони отриманим бітам парності. У наступній таблиці ви бачите, що кожне різноманіття однобітної помилки дає різну відповідність бітів парності. Тому кожну однорозрядну помилку можна локалізувати та виправити.
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
Приклад
Нехай ваші дані будуть 1011
. Біти парності є p1 = 1 + 0 + 1 = 0
, p2 = 1 + 1 + 1 = 1
і p3 = 0 + 1 + 1 = 0
. Об'єднайте дані та біти парності, і ви отримаєте кодове слово 0110011
.
data bits | 1 011
parity bits | 01 0
--------------------
codeword | 0110011
Скажімо, під час передачі чи обчислення 6-й біт (= 3-й біт даних) перегортається. Ви отримуєте слово 0110001
. Передбачувані отримані дані є 1001
. Ви знову обчислити біти парності p1 = 1 + 0 + 1 = 0
, p2 = 1 + 0 + 1 = 0
, p3 = 0 + 0 + 1 = 1
. Тільки p1
відповідає парним бітам кодового слова 0110001
. Тому сталася помилка. Дивлячись на таблицю вище, ми повідомляємо, що сталася помилка, d3
і ви можете відновити вихідні дані 1011
.
Виклик:
Напишіть функцію або програму, яка отримує слово (7 біт), один з бітів може бути неправильним і відновити вихідні дані. Формат введення (через STDIN, аргумент командного рядка, аргумент підказки або аргумент функції) може бути рядком "0110001"
, списком або масивом [0, 1, 1, 0, 0, 0, 1]
або цілим числом в MSB 0b0110001 = 49
. Як описано вище, порядок введення є p1 p2 d1 p3 d2 d3 d4
. Вихід (через повернене значення або STDOUT) повинен бути того самого формату, але в порядку d1 d2 d3 d4
. Повернути / вивести лише 4 біти даних.
Це код-гольф. Тому виграє найкоротший код.
Тестові приклади:
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]
в базі два, це дає положення неправильного біта в цьому слові. (На основі таблиці у запитанні.) Це, мабуть, буде корисним для деяких алгоритмів.