Код Хэмминга (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]
в основу два, это дает позицию неправильного бита в слове. (На основе таблицы в вопросе.) Это, вероятно, будет полезно для некоторых алгоритмов.