Код Хэмминга (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]
в основу два, это дает позицию неправильного бита в слове. (На основе таблицы в вопросе.) Это, вероятно, будет полезно для некоторых алгоритмов.Ответы:
Октава,
706655 байтЭта функция
F
устанавливает матрицу декодированияH
, находит ошибку и корректирует ее положение (если оно есть). Затем он возвращает правильные биты данных. Ввод является стандартным вектором строки.@Jakube предложил мне использовать Octave вместо Matlab, где вы можете использовать индексы для выражений, что снова делает все это короче 11 байтов:
Ниже приводится самое короткое решение в Matlab , так как вы не можете напрямую использовать индексирование для выражений. (Это работает и в Octave, конечно.) Был в состоянии заменить дополнение / mod2 на
xor
:Старый:
источник
http://octave-online.net/
, где он работает. Может поменять язык?Пит 50х11 = 550
Размер кода равен 15. Не слишком обеспокоен размером, но он прошел все тесты.
источник
Python, 79
Возьмите ввод и вывод как числа с младшим значащим битом справа.
Вместо того, чтобы пытаться исправить ошибки, мы просто пытаемся кодировать каждое возможное сообщение
n
от 0 до 15, пока не получим кодировку, которая находится на расстоянии одного бита от того, что дано. Рекурсия продолжает увеличиваться,n
пока не найдет тот, который работает, и не вернет его. Хотя явного завершения нет, оно должно заканчиваться в 16 циклах.Выражение
(n&8)*14^(n&4)*19^(n&2)*21^n%2*105
реализует битовую матрицу Хемминга.Чтобы проверить наличие одной ошибки, мы зашифровываем данное сообщение с вычисленным значением
e
и проверяем, является ли оно степенью двойки (или 0) с помощью классического бит-трюкаe&~-e==0
. Но на самом деле мы не можем присвоить переменнуюe
в лямбде, и мы ссылаемся на нее дважды в этом выражении, поэтому мы делаем хак, передавая ее в качестве необязательного аргумента следующему рекурсивному шагу.источник
JavaScript (ES6),
928781Функция получает и возвращает целое число в MSB.
Реализация проста после комментария @randomra:
Тест в консоли Frefox / FireBug
Выход
источник
Python 2, 71
Несколько символов являются непечатаемыми ASCII, поэтому здесь есть экранированная версия:
Вход и выход в функцию выполняются как целые числа.
Я пользуюсь тем фактом, что количество действительных сообщений составляет всего 16, и жестко их всех кодирую. Затем я пытаюсь переворачивать разные биты, пока не получу один из них.
источник
Haskell, 152 байта
Использование:
a (1,1,1,1,0,1,1)
какие выводы(1,1,1,1)
Простое решение: если
p<x>
не совпадает, установите бит<x>
в число. Если это число3
,5
,6
или7
, флип соответствующийd<y>
.источник
hamming.hs
и загрузить его в GHCI Haskell REPL:ghci hamming.hs
. Вызовите функцию,a
как описано выше. Единственный известный мне онлайн-переводчик haskell ( tryhaskell.org ) требует еще немного кода:let a(p,q, ... 2-y in a (1,1,1,1,0,1,1)
Машинный код IA-32, 36 байтов
HexDump:
Эквивалентный код C:
Процессор x86 автоматически вычисляет четность каждого промежуточного результата. Он имеет специальную инструкцию,
jp
которая прыгает или не прыгает в зависимости от четности.Это не было указано явно в вызове, но удобное свойство кодов Хэмминга заключается в том, что вы можете интерпретировать биты четности как двоичное число, и это число указывает, какой бит был испорчен во время передачи. На самом деле это число основано на 1, причем 0 означает, что ошибок передачи не было. Это реализуется путем смещения 1 влево,
err_pos
а затем вправо1
.После исправления ошибки передачи код размещает биты данных в нужном порядке. Код оптимизирован по размеру, и поначалу может быть неясно, как он работает. Чтобы объяснить это, я обозначу через
a
,b
,c
,d
биты данных, иP
,Q
иR
биты четности. Потом:Источник сборки (
fastcall
соглашение, с входомecx
и выходомeax
):источник