{
  "id": "P076",
  "slug": "hamming-code",
  "key": "P076-hamming-code",
  "title": "Hamming code",
  "summary": "Hamming's (7,4) code: 4 data bits sent as 7 so that one flipped bit is found by the checks that fail and put right; what two or three flips do to it; and the eighth parity bit that turns two flips from a wrong answer into a detected error.",
  "entry": "main.eml",
  "ui": "terminal",
  "readme": "# P076 - Hamming code\n\nHamming's (7,4) code sends 4 data bits as 7. The checks that fail spell\nout which bit flipped, so one flip can be put right. The program shows\nwhat two or three flips do to it, and how an eighth parity bit turns two\nflips from a wrong answer into a detected error.\n\n- `main.eml` - the menu, reading bits and positions, and the reports\n- `hamming.eml` - encoding, the syndrome, correction, flipping, distance,\n  the eighth bit, and all 16 codewords\n\nHow each part works:\n\n- Positions 1 to 7. The parity bits sit at 1, 2 and 4, and the data at\n  3, 5, 6 and 7. Parity bit p covers every position whose number has p in\n  its binary form: p1 covers 1, 3, 5, 7; p2 covers 2, 3, 6, 7; p4 covers\n  4, 5, 6, 7. Each is set so its positions hold an even number of 1s.\n- Receiving: the three checks are run again. Those that fail add up to\n  the syndrome, and a single flip at position k fails exactly the checks\n  that k's binary form names. So the syndrome is k, and bit k is flipped\n  back.\n- Distance, as in the corpus case `hamming-distance`: the number of\n  places two words differ. Any two codewords differ in at least 3, so one\n  flip leaves the received word nearer the word sent than any other.\n- Two flips land nearer a different codeword. The 7-bit decoder always\n  assumes one flip, so it changes a third bit and gives the wrong data.\n  Three flips can even look like none.\n- The eighth bit makes the whole word even. One flip makes the word odd,\n  and is corrected. Two flips leave it even while the checks fail, so the\n  error is detected but not corrected: ask again. Three flips look like\n  one, so that is wrong too.\n\nWhat is checked: menu choices 1 to 5; exactly 4 or 7 bits, 0 or 1\n(spaces ignored); 1 to 3 different positions from 1 to 7. An empty answer\ncancels.\n\nSessions: `sessions/basic.in` gives:\n- 1011 sent as 0110011;\n- 0110111 received: the checks point at 5, and 1011 comes back; then\n  0110011, which passes;\n- 1011 with position 5 flipped (corrected), with 3 and 5 (wrong with 7\n  bits, detected with 8), and with 1, 2 and 3 (passes every check, wrong);\n- 0000 with 1, 2 and 4 flipped, wrong both ways;\n- all 16 codewords, at least 3 places apart.\n\n`sessions/bad-input.in` gives:\n- menu choices 0 and x;\n- data 101 and 10a1, a 4-bit word where 7 are needed, then cancels;\n- positions 8, \"3 3\" and four positions, then a cancel.\n\nBuilt on the verified corpus case `hamming-distance` (counting the places\ntwo equal-length words differ).\n",
  "modules": [
    {
      "name": "main.eml",
      "eml": "# P076 Hamming code: 4 data bits sent as 7, any one flipped bit found and\n# put right; what two flips do to it; and the eighth parity bit that turns\n# two flips from a wrong answer into a detected error.\nimport hamming\n\ndef trim(s):\n    0 => i\n    len(s) => j\n    while i < j and s[i] == \" \":\n        i + 1 => i\n    while j > i and s[j - 1] == \" \":\n        j - 1 => j\n    return s[i:j]\n\ndef bits_of(s, n):\n    # \"1011\" -> [1, 0, 1, 1] if s is exactly n bits (spaces ignored), else [].\n    [] => out\n    for c in s:\n        if c == \"0\":\n            out + [0] => out\n        elif c == \"1\":\n            out + [1] => out\n        elif c != \" \":\n            return []\n    if len(out) != n:\n        return []\n    return out\n\ndef text(bits):\n    \"\" => s\n    for b in bits:\n        s + str(b) => s\n    return s\n\ndef positions_of(s):\n    # \"3 5\" -> [3, 5]: one to three different positions from 1 to 7.\n    [] => out\n    for c in s:\n        if c >= \"1\" and c <= \"7\":\n            for p in out:\n                if p == int(c):\n                    return []\n            out + [int(c)] => out\n        elif c != \" \" and c != \",\":\n            return []\n    if len(out) == 0 or len(out) > 3:\n        return []\n    return out\n\ndef ask_bits(prompt, n):\n    while True:\n        trim(input(prompt)) => s\n        if s == \"\":\n            return []\n        bits_of(s, n) => b\n        if len(b) == n:\n            return b\n        (\"Type exactly \" + str(n) + \" bits, 0 or 1.\") ^0\n\ndef layout(c):\n    \"  position  1  2  3  4  5  6  7\" ^0\n    \"  role     p1 p2 d1 p4 d2 d3 d4\" ^0\n    \"\" => line\n    for b in c:\n        line + \"  \" + str(b) => line\n    (\"  bit     \" + line) ^0\n\ndef send():\n    ask_bits(\"4 data bits (like 1011)> \", 4) => d\n    if len(d) == 0:\n        \"Cancelled.\" ^0\n        return\n    hamming.encode(d) => c\n    layout(c)\n    \"  p1 makes positions 1, 3, 5, 7 even; p2 makes 2, 3, 6, 7 even; p4 makes 4, 5, 6, 7 even.\" ^0\n    (text(d) + \" is sent as \" + text(c) + \".\") ^0\n\ndef receive():\n    ask_bits(\"7 bits received> \", 7) => c\n    if len(c) == 0:\n        \"Cancelled.\" ^0\n        return\n    hamming.correct(c) => r\n    layout(c)\n    if r[0] == 0:\n        (\"All three checks pass: the data is \" + text(hamming.data_of(c)) + \".\") ^0\n    else:\n        (\"The checks that fail add up to \" + str(r[0]) + \", so position \" + str(r[0]) + \" is flipped back: \" + text(r[1]) + \", data \" + text(hamming.data_of(r[1])) + \".\") ^0\n\ndef experiment():\n    ask_bits(\"4 data bits (like 1011)> \", 4) => d\n    if len(d) == 0:\n        \"Cancelled.\" ^0\n        return\n    while True:\n        trim(input(\"positions to flip (1 to 3 of 1-7, like 3 5)> \")) => s\n        if s == \"\":\n            \"Cancelled.\" ^0\n            return\n        positions_of(s) => ps\n        if len(ps) > 0:\n            hamming.encode(d) => c\n            hamming.flipped(c, ps) => bad\n            hamming.correct(bad) => r\n            hamming.data_of(r[1]) => got\n            (\"sent \" + text(c) + \", received \" + text(bad) + \" - \" + str(len(ps)) + \" flipped.\") ^0\n            if r[0] == 0:\n                (\"7 bits: every check passes, so the decoder takes it as sent - data \" + text(got) + \".\") ^0\n            else:\n                (\"7 bits: the checks point at position \" + str(r[0]) + \"; flipping it back gives data \" + text(got) + \".\") ^0\n            if got == d:\n                \"  That is right.\" ^0\n            else:\n                (\"  That is wrong: \" + text(d) + \" was sent. The 7-bit code always assumes one flip, and cannot tell more from one.\") ^0\n            hamming.with_parity(c) => w\n            hamming.flipped(w, ps) => wbad\n            hamming.secded(wbad) => v\n            if v[0] == \"two errors\":\n                (\"8 bits (an eighth bit making the word even): the checks fail but the word is still even, so two bits changed - detected, not corrected; ask again.\") ^0\n            elif v[0] == \"corrected\":\n                (\"8 bits (an eighth bit making the word even): it looks like one flip, so it corrects it - data \" + text(v[1]) + \".\") ^0\n            else:\n                (\"8 bits (an eighth bit making the word even): every check passes - data \" + text(v[1]) + \".\") ^0\n            if v[0] != \"two errors\" and v[1] != d:\n                \"  That is wrong too: to the eighth bit, three flips look like one.\" ^0\n            return\n        \"Type 1 to 3 different positions from 1 to 7, like 3 5.\" ^0\n\ndef table():\n    hamming.codewords() => cs\n    \"  data  codeword\" ^0\n    for n in [0:15]:\n        (\"  \" + text(cs[n][2:3] + cs[n][4:7]) + \"  \" + text(cs[n])) ^0\n    16 => fewest\n    for i in [0:15]:\n        for j in [i + 1:15]:\n            hamming.distance(cs[i], cs[j]) => k\n            if k < fewest:\n                k => fewest\n    (\"Any two codewords differ in at least \" + str(fewest) + \" places, so one flip leaves a word nearer the one sent than any other, and two flips can land nearer a different one.\") ^0\n\n\"== Hamming code ==\" ^0\n\"Hamming's (7,4) code: 4 data bits sent as 7, so one flipped bit can be found and put right.\" ^0\nTrue => running\nwhile running:\n    \"\" ^0\n    \"1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\" ^0\n    trim(input(\"choice> \")) => choice\n    if choice == \"1\":\n        send()\n    elif choice == \"2\":\n        receive()\n    elif choice == \"3\":\n        experiment()\n    elif choice == \"4\":\n        table()\n    elif choice == \"5\":\n        False => running\n    else:\n        \"Pick a number from 1 to 5.\" ^0\n\"Bye.\" ^0\n",
      "python": "import hamming\n\ndef trim(s):\n    i = 0\n    j = len(s)\n    while i < j and s[i] == \" \":\n        i = i + 1\n    while j > i and s[j - 1] == \" \":\n        j = j - 1\n    return s[i:j]\n\ndef bits_of(s, n):\n    out = []\n    for c in s:\n        if c == \"0\":\n            out = out + [0]\n        elif c == \"1\":\n            out = out + [1]\n        elif c != \" \":\n            return []\n    if len(out) != n:\n        return []\n    return out\n\ndef text(bits):\n    s = \"\"\n    for b in bits:\n        s = s + str(b)\n    return s\n\ndef positions_of(s):\n    out = []\n    for c in s:\n        if c >= \"1\" and c <= \"7\":\n            for p in out:\n                if p == int(c):\n                    return []\n            out = out + [int(c)]\n        elif c != \" \" and c != \",\":\n            return []\n    if len(out) == 0 or len(out) > 3:\n        return []\n    return out\n\ndef ask_bits(prompt, n):\n    while True:\n        s = trim(input(prompt))\n        if s == \"\":\n            return []\n        b = bits_of(s, n)\n        if len(b) == n:\n            return b\n        print(\"Type exactly \" + str(n) + \" bits, 0 or 1.\")\n\ndef layout(c):\n    print(\"  position  1  2  3  4  5  6  7\")\n    print(\"  role     p1 p2 d1 p4 d2 d3 d4\")\n    line = \"\"\n    for b in c:\n        line = line + \"  \" + str(b)\n    print(\"  bit     \" + line)\n\ndef send():\n    d = ask_bits(\"4 data bits (like 1011)> \", 4)\n    if len(d) == 0:\n        print(\"Cancelled.\")\n        return\n    c = hamming.encode(d)\n    layout(c)\n    print(\"  p1 makes positions 1, 3, 5, 7 even; p2 makes 2, 3, 6, 7 even; p4 makes 4, 5, 6, 7 even.\")\n    print(text(d) + \" is sent as \" + text(c) + \".\")\n\ndef receive():\n    c = ask_bits(\"7 bits received> \", 7)\n    if len(c) == 0:\n        print(\"Cancelled.\")\n        return\n    r = hamming.correct(c)\n    layout(c)\n    if r[0] == 0:\n        print(\"All three checks pass: the data is \" + text(hamming.data_of(c)) + \".\")\n    else:\n        print(\"The checks that fail add up to \" + str(r[0]) + \", so position \" + str(r[0]) + \" is flipped back: \" + text(r[1]) + \", data \" + text(hamming.data_of(r[1])) + \".\")\n\ndef experiment():\n    d = ask_bits(\"4 data bits (like 1011)> \", 4)\n    if len(d) == 0:\n        print(\"Cancelled.\")\n        return\n    while True:\n        s = trim(input(\"positions to flip (1 to 3 of 1-7, like 3 5)> \"))\n        if s == \"\":\n            print(\"Cancelled.\")\n            return\n        ps = positions_of(s)\n        if len(ps) > 0:\n            c = hamming.encode(d)\n            bad = hamming.flipped(c, ps)\n            r = hamming.correct(bad)\n            got = hamming.data_of(r[1])\n            print(\"sent \" + text(c) + \", received \" + text(bad) + \" - \" + str(len(ps)) + \" flipped.\")\n            if r[0] == 0:\n                print(\"7 bits: every check passes, so the decoder takes it as sent - data \" + text(got) + \".\")\n            else:\n                print(\"7 bits: the checks point at position \" + str(r[0]) + \"; flipping it back gives data \" + text(got) + \".\")\n            if got == d:\n                print(\"  That is right.\")\n            else:\n                print(\"  That is wrong: \" + text(d) + \" was sent. The 7-bit code always assumes one flip, and cannot tell more from one.\")\n            w = hamming.with_parity(c)\n            wbad = hamming.flipped(w, ps)\n            v = hamming.secded(wbad)\n            if v[0] == \"two errors\":\n                print(\"8 bits (an eighth bit making the word even): the checks fail but the word is still even, so two bits changed - detected, not corrected; ask again.\")\n            elif v[0] == \"corrected\":\n                print(\"8 bits (an eighth bit making the word even): it looks like one flip, so it corrects it - data \" + text(v[1]) + \".\")\n            else:\n                print(\"8 bits (an eighth bit making the word even): every check passes - data \" + text(v[1]) + \".\")\n            if v[0] != \"two errors\" and v[1] != d:\n                print(\"  That is wrong too: to the eighth bit, three flips look like one.\")\n            return\n        print(\"Type 1 to 3 different positions from 1 to 7, like 3 5.\")\n\ndef table():\n    cs = hamming.codewords()\n    print(\"  data  codeword\")\n    for n in range(0, 16):\n        print(\"  \" + text(cs[n][2:3] + cs[n][4:7]) + \"  \" + text(cs[n]))\n    fewest = 16\n    for i in range(0, 16):\n        for j in range(i + 1, 16):\n            k = hamming.distance(cs[i], cs[j])\n            if k < fewest:\n                fewest = k\n    print(\"Any two codewords differ in at least \" + str(fewest) + \" places, so one flip leaves a word nearer the one sent than any other, and two flips can land nearer a different one.\")\n\nprint(\"== Hamming code ==\")\nprint(\"Hamming's (7,4) code: 4 data bits sent as 7, so one flipped bit can be found and put right.\")\nrunning = True\nwhile running:\n    print(\"\")\n    print(\"1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\")\n    choice = trim(input(\"choice> \"))\n    if choice == \"1\":\n        send()\n    elif choice == \"2\":\n        receive()\n    elif choice == \"3\":\n        experiment()\n    elif choice == \"4\":\n        table()\n    elif choice == \"5\":\n        running = False\n    else:\n        print(\"Pick a number from 1 to 5.\")\nprint(\"Bye.\")\n"
    },
    {
      "name": "hamming.eml",
      "eml": "# P076 Hamming code - Hamming's (7,4) code: 4 data bits sent as 7, so that\n# any one flipped bit can be found and put right. Positions 1 to 7; the\n# parity bits sit at 1, 2 and 4, the data at 3, 5, 6 and 7. Parity bit p\n# covers every position whose number has p in its binary form, so the\n# three checks that fail spell out, in binary, the position that flipped.\n# Bits are lists of 0 and 1; index 0 is position 1.\n\ndef xor(a, b):\n    return (a + b) % 2\n\ndef covers(p, pos):\n    # Whether parity bit p (1, 2 or 4) covers position pos: bit p of pos.\n    pos => n\n    p => q\n    while q > 1:\n        int((n - n % 2) / 2) => n\n        int(q / 2) => q\n    return n % 2 == 1\n\ndef encode(data):\n    # [d1, d2, d3, d4] -> the 7 bits [p1, p2, d1, p4, d2, d3, d4].\n    [0, 0, data[0], 0, data[1], data[2], data[3]] => c\n    for p in [1, 2, 4]:\n        0 => s\n        for pos in [1:7]:\n            if pos != p and covers(p, pos):\n                xor(s, c[pos - 1]) => s\n        s => c[p - 1]\n    return c\n\ndef syndrome(c):\n    # Re-run the three checks; each that fails adds its p. 0 means every\n    # check passes; otherwise it is the position a single flip would be at.\n    0 => out\n    for p in [1, 2, 4]:\n        0 => s\n        for pos in [1:7]:\n            if covers(p, pos):\n                xor(s, c[pos - 1]) => s\n        if s == 1:\n            out + p => out\n    return out\n\ndef data_of(c):\n    return [c[2], c[4], c[5], c[6]]\n\ndef correct(c):\n    # [the syndrome, the 7 bits with that position flipped back].\n    syndrome(c) => s\n    [0] * 7 => out\n    for i in [0:6]:\n        c[i] => out[i]\n    if s > 0:\n        xor(out[s - 1], 1) => out[s - 1]\n    return [s, out]\n\ndef flipped(c, positions):\n    # A copy of the bits with the given positions (1-based) flipped.\n    [0] * len(c) => out\n    for i in [0:len(c) - 1]:\n        c[i] => out[i]\n    for p in positions:\n        xor(out[p - 1], 1) => out[p - 1]\n    return out\n\ndef distance(a, b):\n    # The corpus case hamming-distance: how many positions differ.\n    0 => d\n    for i in [0:len(a) - 1]:\n        if a[i] != b[i]:\n            d + 1 => d\n    return d\n\ndef with_parity(c):\n    # The extended (8,4) code: an eighth bit makes the whole word even.\n    0 => s\n    for b in c:\n        xor(s, b) => s\n    return c + [s]\n\ndef secded(w):\n    # Decoding the 8-bit word: one flip is corrected; two are detected but\n    # cannot be corrected - the syndrome says something is wrong while the\n    # overall parity says an even number of bits changed. Returns\n    # [verdict, data or []] with verdict \"ok\", \"corrected\" or \"two errors\".\n    syndrome(w[0:7]) => s\n    0 => total\n    for b in w:\n        xor(total, b) => total\n    if s == 0 and total == 0:\n        return [\"ok\", data_of(w)]\n    if total == 1:\n        if s == 0:\n            return [\"corrected\", data_of(w)]\n        return [\"corrected\", data_of(correct(w[0:7])[1])]\n    return [\"two errors\", []]\n\ndef codewords():\n    # All 16 codewords, in the order of their data bits 0000 to 1111.\n    [] => out\n    for n in [0:15]:\n        [0, 0, 0, 0] => d\n        n => r\n        for i in [0:3]:\n            r % 2 => d[3 - i]\n            int((r - r % 2) / 2) => r\n        out + [encode(d)] => out\n    return out\n",
      "python": "def xor(a, b):\n    return (a + b) % 2\n\ndef covers(p, pos):\n    n = pos\n    q = p\n    while q > 1:\n        n = int((n - n % 2) / 2)\n        q = int(q / 2)\n    return n % 2 == 1\n\ndef encode(data):\n    c = [0, 0, data[0], 0, data[1], data[2], data[3]]\n    for p in [1, 2, 4]:\n        s = 0\n        for pos in range(1, 8):\n            if pos != p and covers(p, pos):\n                s = xor(s, c[pos - 1])\n        c[p - 1] = s\n    return c\n\ndef syndrome(c):\n    out = 0\n    for p in [1, 2, 4]:\n        s = 0\n        for pos in range(1, 8):\n            if covers(p, pos):\n                s = xor(s, c[pos - 1])\n        if s == 1:\n            out = out + p\n    return out\n\ndef data_of(c):\n    return [c[2], c[4], c[5], c[6]]\n\ndef correct(c):\n    s = syndrome(c)\n    out = [0] * 7\n    for i in range(0, 7):\n        out[i] = c[i]\n    if s > 0:\n        out[s - 1] = xor(out[s - 1], 1)\n    return [s, out]\n\ndef flipped(c, positions):\n    out = [0] * len(c)\n    for i in range(0, len(c)):\n        out[i] = c[i]\n    for p in positions:\n        out[p - 1] = xor(out[p - 1], 1)\n    return out\n\ndef distance(a, b):\n    d = 0\n    for i in range(0, len(a)):\n        if a[i] != b[i]:\n            d = d + 1\n    return d\n\ndef with_parity(c):\n    s = 0\n    for b in c:\n        s = xor(s, b)\n    return c + [s]\n\ndef secded(w):\n    s = syndrome(w[0:7])\n    total = 0\n    for b in w:\n        total = xor(total, b)\n    if s == 0 and total == 0:\n        return [\"ok\", data_of(w)]\n    if total == 1:\n        if s == 0:\n            return [\"corrected\", data_of(w)]\n        return [\"corrected\", data_of(correct(w[0:7])[1])]\n    return [\"two errors\", []]\n\ndef codewords():\n    out = []\n    for n in range(0, 16):\n        d = [0, 0, 0, 0]\n        r = n\n        for i in range(0, 4):\n            d[3 - i] = r % 2\n            r = int((r - r % 2) / 2)\n        out = out + [encode(d)]\n    return out\n"
    }
  ],
  "sessions": [
    {
      "name": "bad-input",
      "input": "0\nx\n1\n101\n10a1\n\n2\n0110\n\n3\n1011\n8\n3 3\n1 2 3 4\n\n5\n",
      "screen": "== Hamming code ==\nHamming's (7,4) code: 4 data bits sent as 7, so one flipped bit can be found and put right.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 0\nPick a number from 1 to 5.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> x\nPick a number from 1 to 5.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 1\n4 data bits (like 1011)> 101\nType exactly 4 bits, 0 or 1.\n4 data bits (like 1011)> 10a1\nType exactly 4 bits, 0 or 1.\n4 data bits (like 1011)> \nCancelled.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 2\n7 bits received> 0110\nType exactly 7 bits, 0 or 1.\n7 bits received> \nCancelled.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 3\n4 data bits (like 1011)> 1011\npositions to flip (1 to 3 of 1-7, like 3 5)> 8\nType 1 to 3 different positions from 1 to 7, like 3 5.\npositions to flip (1 to 3 of 1-7, like 3 5)> 3 3\nType 1 to 3 different positions from 1 to 7, like 3 5.\npositions to flip (1 to 3 of 1-7, like 3 5)> 1 2 3 4\nType 1 to 3 different positions from 1 to 7, like 3 5.\npositions to flip (1 to 3 of 1-7, like 3 5)> \nCancelled.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 5\nBye.\n",
      "interpreter": "equal"
    },
    {
      "name": "basic",
      "input": "1\n1011\n2\n0110111\n2\n0110011\n3\n1011\n5\n3\n1011\n3 5\n3\n1011\n1 2 3\n3\n0000\n1 2 4\n4\n5\n",
      "screen": "== Hamming code ==\nHamming's (7,4) code: 4 data bits sent as 7, so one flipped bit can be found and put right.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 1\n4 data bits (like 1011)> 1011\n  position  1  2  3  4  5  6  7\n  role     p1 p2 d1 p4 d2 d3 d4\n  bit       0  1  1  0  0  1  1\n  p1 makes positions 1, 3, 5, 7 even; p2 makes 2, 3, 6, 7 even; p4 makes 4, 5, 6, 7 even.\n1011 is sent as 0110011.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 2\n7 bits received> 0110111\n  position  1  2  3  4  5  6  7\n  role     p1 p2 d1 p4 d2 d3 d4\n  bit       0  1  1  0  1  1  1\nThe checks that fail add up to 5, so position 5 is flipped back: 0110011, data 1011.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 2\n7 bits received> 0110011\n  position  1  2  3  4  5  6  7\n  role     p1 p2 d1 p4 d2 d3 d4\n  bit       0  1  1  0  0  1  1\nAll three checks pass: the data is 1011.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 3\n4 data bits (like 1011)> 1011\npositions to flip (1 to 3 of 1-7, like 3 5)> 5\nsent 0110011, received 0110111 - 1 flipped.\n7 bits: the checks point at position 5; flipping it back gives data 1011.\n  That is right.\n8 bits (an eighth bit making the word even): it looks like one flip, so it corrects it - data 1011.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 3\n4 data bits (like 1011)> 1011\npositions to flip (1 to 3 of 1-7, like 3 5)> 3 5\nsent 0110011, received 0100111 - 2 flipped.\n7 bits: the checks point at position 6; flipping it back gives data 0101.\n  That is wrong: 1011 was sent. The 7-bit code always assumes one flip, and cannot tell more from one.\n8 bits (an eighth bit making the word even): the checks fail but the word is still even, so two bits changed - detected, not corrected; ask again.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 3\n4 data bits (like 1011)> 1011\npositions to flip (1 to 3 of 1-7, like 3 5)> 1 2 3\nsent 0110011, received 1000011 - 3 flipped.\n7 bits: every check passes, so the decoder takes it as sent - data 0011.\n  That is wrong: 1011 was sent. The 7-bit code always assumes one flip, and cannot tell more from one.\n8 bits (an eighth bit making the word even): it looks like one flip, so it corrects it - data 0011.\n  That is wrong too: to the eighth bit, three flips look like one.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 3\n4 data bits (like 1011)> 0000\npositions to flip (1 to 3 of 1-7, like 3 5)> 1 2 4\nsent 0000000, received 1101000 - 3 flipped.\n7 bits: the checks point at position 7; flipping it back gives data 0001.\n  That is wrong: 0000 was sent. The 7-bit code always assumes one flip, and cannot tell more from one.\n8 bits (an eighth bit making the word even): it looks like one flip, so it corrects it - data 0001.\n  That is wrong too: to the eighth bit, three flips look like one.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 4\n  data  codeword\n  0000  0000000\n  0001  1101001\n  0010  0101010\n  0011  1000011\n  0100  1001100\n  0101  0100101\n  0110  1100110\n  0111  0001111\n  1000  1110000\n  1001  0011001\n  1010  1011010\n  1011  0110011\n  1100  0111100\n  1101  1010101\n  1110  0010110\n  1111  1111111\nAny two codewords differ in at least 3 places, so one flip leaves a word nearer the one sent than any other, and two flips can land nearer a different one.\n\n1) send  2) receive  3) flip bits and see  4) all 16 codewords  5) quit\nchoice> 5\nBye.\n",
      "interpreter": "equal"
    }
  ],
  "builtOn": [
    {
      "slug": "hamming-distance",
      "caseId": "100-hamming-distance",
      "title": "Hamming distance"
    }
  ],
  "updated": "2026-10-14"
}
