Kode Hamming (7,4) kembali ke tahun 1950. Saat itu Richard Hamming bekerja sebagai ahli matematika di Bell Labs. Setiap Jumat, Hamming mengatur mesin penghitung untuk melakukan serangkaian perhitungan, dan mengumpulkan hasilnya pada hari Senin berikutnya. Menggunakan pemeriksaan paritas, mesin-mesin ini dapat mendeteksi kesalahan selama perhitungan. Frustrasi, karena terlalu sering menerima pesan kesalahan, Hamming memutuskan untuk meningkatkan deteksi kesalahan dan menemukan kode Hamming yang terkenal.
Mekanika Hamming (7,4)
Tujuan dari kode Hamming adalah untuk membuat satu set bit paritas yang tumpang tindih sehingga kesalahan bit tunggal (satu bit dibalik) dalam bit data atau bit paritas dapat dideteksi dan diperbaiki. Hanya jika ada beberapa kesalahan, kode Hamming gagal memulihkan data asli. Mungkin tidak melihat kesalahan sama sekali, atau bahkan memperbaikinya dengan salah. Karenanya dalam tantangan ini kita hanya akan berurusan dengan kesalahan bit-tunggal.
Sebagai contoh kode Hamming, kita akan melihat kode Hamming (7,4). Selain itu untuk 4 bit data d1, d2, d3, d4
menggunakan 3 bit paritas p1, p2, p3
, yang dihitung menggunakan persamaan berikut:
p1 = (d1 + d2 + d4) % 2
p2 = (d1 + d3 + d4) % 2
p3 = (d2 + d3 + d4) % 2
Codeword yang dihasilkan (bit data + paritas) berbentuk form p1 p2 d1 p3 d2 d3 d4
.
Mendeteksi kesalahan berfungsi sebagai berikut. Anda menghitung ulang bit paritas, dan memeriksa apakah cocok dengan bit paritas yang diterima. Dalam tabel berikut, Anda dapat melihat, bahwa setiap variasi kesalahan bit tunggal menghasilkan pencocokan yang berbeda dari bit paritas. Oleh karena itu setiap kesalahan bit tunggal dapat dilokalkan dan diperbaiki.
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
Contoh
Biarkan data Anda 1011
. Bit paritas adalah p1 = 1 + 0 + 1 = 0
, p2 = 1 + 1 + 1 = 1
dan p3 = 0 + 1 + 1 = 0
. Gabungkan data dan bit paritas dan Anda mendapatkan kata sandi 0110011
.
data bits | 1 011
parity bits | 01 0
--------------------
codeword | 0110011
Katakanlah selama transmisi atau perhitungan bit ke-6 (= bit data ke-3) terbalik. Anda menerima kata itu 0110001
. Data yang diterima diduga adalah 1001
. Anda menghitung paritas bit lagi p1 = 1 + 0 + 1 = 0
, p2 = 1 + 0 + 1 = 0
, p3 = 0 + 0 + 1 = 1
. Hanya p1
cocok dengan bit paritas codeword 0110001
. Karenanya terjadi kesalahan. Melihat tabel di atas, memberi tahu kami bahwa kesalahan terjadi d3
dan Anda dapat memulihkan data asli 1011
.
Tantangan:
Tulis fungsi atau program, yang menerima kata (7 bit), salah satu bit mungkin salah, dan pulihkan data aslinya. Format input (melalui STDIN, argumen baris perintah, argumen cepat atau fungsi) dapat berupa string "0110001"
, daftar atau array [0, 1, 1, 0, 0, 0, 1]
atau integer di MSB 0b0110001 = 49
. Seperti dijelaskan di atas, urutan input adalah p1 p2 d1 p3 d2 d3 d4
. Output (melalui nilai balik atau STDOUT) harus dalam format yang sama, tetapi dalam urutand1 d2 d3 d4
. Hanya kembalikan / hasilkan 4 bit data.
Ini adalah kode-golf. Karenanya kode terpendek menang.
Kasus uji:
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]
di basis dua itu memberikan posisi bit yang salah dalam kata. (Berdasarkan tabel pada pertanyaan.) Ini mungkin akan berguna untuk beberapa algoritma.Jawaban:
Oktaf,
706655 byteFungsi
F
ini mengatur matriks decodingH
, menemukan kesalahan dan memperbaiki posisi kesalahan (jika ada). Kemudian mengembalikan bit data yang benar. Input adalah vektor baris standar.@ Jakube menyarankan saya harus menggunakan Oktaf daripada Matlab di mana Anda dapat menggunakan indeks pada ekspresi, yang membuat semuanya lagi lebih pendek 11 byte:
Berikut ini adalah solusi terpendek di Matlab , karena Anda tidak bisa langsung menggunakan pengindeksan pada ekspresi. (Ini bekerja di oktaf juga, tentu saja.) Mampu mengganti penambahan / mod2 dengan
xor
:Tua:
sumber
http://octave-online.net/
, di mana ia bekerja Mungkin mengubah bahasa?Piet 50x11 = 550
ukuran codel adalah 15. Tidak terlalu peduli tentang ukuran, tetapi melewati semua tes.
sumber
Python, 79
Ambil input dan output sebagai angka dengan bit paling signifikan di sebelah kanan.
Alih-alih mencoba pemulihan kesalahan, kami hanya mencoba menyandikan setiap pesan yang mungkin
n
dari 0 hingga 15 hingga kami mendapatkan penyandian yang agak jauh dari yang diberikan. Rekursi terus bertambahn
hingga menemukan yang berfungsi dan mengembalikannya. Meskipun tidak ada penghentian eksplisit, itu harus berakhir dalam 16 loop.Ekspresi
(n&8)*14^(n&4)*19^(n&2)*21^n%2*105
mengimplementasikan matriks Hamming bitwise.Untuk memeriksa satu kesalahan, kami memperbaiki pesan yang diberikan dengan yang dihitung
e
, dan memeriksa apakah kekuatan dua (atau 0) dengan bit-trick klasike&~-e==0
. Tapi, kita tidak bisa benar-benar menetapkan variabele
dalam lambda, dan kita merujuknya dua kali dalam ekspresi ini, jadi kita melakukan hack untuk meneruskannya sebagai argumen opsional ke langkah rekursif berikutnya.sumber
JavaScript (ES6),
928781Berfungsi mendapatkan dan mengembalikan integer di MSB.
Implementasinya sangat mudah berikut komentar @randomra:
Tes di konsol Frefox / FireBug
Keluaran
sumber
Python 2, 71
Beberapa karakter adalah ASCII yang tidak dapat dicetak, jadi ini adalah versi yang lolos:
Input dan output ke fungsi dilakukan sebagai bilangan bulat.
Saya mengambil keuntungan dari kenyataan bahwa jumlah pesan yang valid hanya 16, dan mengkodekan semuanya. Lalu saya mencoba membalik bit yang berbeda sampai saya mendapatkan salah satunya.
sumber
Haskell, 152 byte
Penggunaan:
a (1,1,1,1,0,1,1)
output mana(1,1,1,1)
Solusi mudah: jika
p<x>
tidak cocok, atur bit<x>
dalam angka. Jika angka ini3
,5
,6
atau7
, flip yang sesuaid<y>
.sumber
hamming.hs
dan beban ke dalam ghci Haskell repl:ghci hamming.hs
. Panggil fungsia
seperti dijelaskan di atas. Satu-satunya juru bahasa haskell online yang saya ketahui ( tryhaskell.org ) memerlukan beberapa kode lagi:let a(p,q, ... 2-y in a (1,1,1,1,0,1,1)
Kode mesin IA-32, 36 byte
Hexdump:
Kode C Setara:
CPU x86 secara otomatis menghitung paritas dari setiap hasil antara. Ini memiliki instruksi khusus
jp
yang melompat atau tidak melompat tergantung pada paritas.Itu tidak ditentukan secara eksplisit dalam tantangan, tetapi properti nyaman dari kode hamming adalah bahwa Anda dapat menafsirkan bit paritas sebagai angka biner, dan angka ini menunjukkan bit mana yang rusak selama transmisi. Sebenarnya, nomor ini berbasis 1, dengan 0 artinya tidak ada kesalahan transmisi. Ini diimplementasikan dengan menggeser 1 ke kiri
err_pos
lalu ke kanan1
.Setelah memperbaiki kesalahan transmisi, kode mengatur bit data dalam urutan yang diperlukan. Kode dioptimalkan untuk ukuran, dan mungkin tidak jelas pada awalnya cara kerjanya. Untuk menjelaskannya, saya menyatakan dengan
a
,b
,c
,d
bit data, dan olehP
,Q
danR
paritas bit. Kemudian:Sumber perakitan (
fastcall
konvensi, dengan input masukecx
, dan keluaran masukeax
):sumber