{
  "id": "P100",
  "slug": "mastermind",
  "key": "P100-mastermind",
  "title": "Mastermind",
  "summary": "Codes of 4 colours from 6, scored black and white by counting colours: play against a secret code with the codes still possible counted after each answer, watch the computer's rule solve any code, or see how one guess is scored.",
  "entry": "main.eml",
  "ui": "terminal",
  "readme": "# P100 - Mastermind\n\nCodes of 4 colours, each from 1 to 6, repeats allowed: 1,296 of them.\nYou can guess the computer's code, watch the computer guess yours, or see\nhow one guess is scored.\n\n- `main.eml` - the menu, playing, watching and scoring\n- `pegs.eml` - every code, scoring, the codes that fit an answer, the\n  computer's rule and the secret code\n\nHow each part works:\n\n- A guess is answered with black (the right colour in the right place)\n  and white (the right colour in the wrong place). Colours are counted\n  with a dict, as in the corpus case `char-frequency-table`. Each colour\n  is in both codes as often as the smaller of its two counts. The total\n  of those, minus black, is white.\n- After each answer, the codes still possible are the ones that would\n  have given the same answer to the same guess. The program counts them\n  and can give one as a hint. It also says when a guess could not have\n  been the code.\n- The computer's rule: guess 1122, then the first code, in order, that\n  fits every answer so far. Over all 1,296 codes it never needs more than\n  8 guesses: 6,508 in all, 5.02 a code.\n- The secret code comes from a seed, through a linear congruential\n  generator.\n\nWhat is checked: menu choices 1 to 4; a seed from 0 to 999999; codes of\n4 colours, each from 1 to 6. An empty answer cancels. While playing, it\nstops the game and shows the code.\n\nSessions: `sessions/basic.in` gives:\n- a game (seed 7): two guesses that could not have been the code, two\n  hints, and the code found in 4 guesses;\n- a game given up after two guesses (seed 42);\n- the computer solving 3456 and 1511 in 5 guesses, and 6543 in 7;\n- three scores: 1234 against 1325, 1122 against 2211, and 6666 against\n  6616.\n\n`sessions/bad-input.in` gives:\n- menu choices 0 and x; the seed x, then a cancel;\n- the guesses 123, 12345, 1237 and abcd; then 1111 ten times, until no\n  guesses are left;\n- a cancel, 777, and a random code whose seed is cancelled;\n- scores with 12, and two cancels.\n\nBuilt on the verified corpus case `char-frequency-table` (counting with\na dict, one character at a time).\n",
  "modules": [
    {
      "name": "main.eml",
      "eml": "# P100 Mastermind: guess the computer's code, watch the computer guess\n# yours, or see how one guess is scored.\nimport pegs\n\ndef plain(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 number(s, most):\n    if len(s) == 0 or len(s) > most:\n        return -1\n    0 => n\n    for c in s:\n        if not (c >= \"0\" and c <= \"9\"):\n            return -1\n        n * 10 + int(c) => n\n    return n\n\ndef lpad(s, n):\n    while len(s) < n:\n        \" \" + s => s\n    return s\n\ndef answer(r):\n    return str(r[0]) + \" black, \" + str(r[1]) + \" white\"\n\ndef still(n):\n    if n == 1:\n        return \"1 code still fits every answer.\"\n    return str(n) + \" codes still fit every answer.\"\n\ndef ask_seed():\n    while True:\n        plain(input(\"seed (0 to 999999)> \")) => a\n        if a == \"\":\n            return -1\n        number(a, 6) => n\n        if n >= 0:\n            return n\n        \"Type a whole number from 0 to 999999.\" ^0\n\ndef play():\n    ask_seed() => seed\n    if seed == -1:\n        \"Cancelled.\" ^0\n        return\n    pegs.secret(seed) => code\n    \"I have picked a code: 4 colours, each 1 to 6, repeats allowed. You have 10 guesses.\" ^0\n    pegs.all_codes() => left\n    1 => turn\n    while turn <= 10:\n        plain(input(\"guess \" + str(turn) + \" (4 colours 1 to 6, ? for a hint)> \")) => g\n        if g == \"\":\n            (\"You stopped. The code was \" + code + \".\") ^0\n            return\n        if g == \"?\":\n            (\"A code that fits every answer so far: \" + left[0] + \".\") ^0\n        elif not pegs.valid(g):\n            \"Type 4 colours, each 1 to 6, like 1234.\" ^0\n        else:\n            pegs.score(g, code) => r\n            False => fitted\n            for c in left:\n                if c == g:\n                    True => fitted\n            pegs.fits(left, g, r) => left\n            if r[0] == 4:\n                (\"4 black: that is the code, in \" + str(turn) + \" guesses.\") ^0\n                return\n            if fitted:\n                (answer(r) + \". \" + still(len(left))) ^0\n            else:\n                (answer(r) + \". \" + still(len(left)) + \" (That guess could not have been the code: it did not fit an earlier answer.)\") ^0\n            turn + 1 => turn\n    (\"No guesses left. The code was \" + code + \".\") ^0\n\ndef watch():\n    plain(input(\"your code (4 colours 1 to 6), or random> \")) => s\n    if s == \"\":\n        \"Cancelled.\" ^0\n        return\n    if s == \"random\":\n        ask_seed() => seed\n        if seed == -1:\n            \"Cancelled.\" ^0\n            return\n        pegs.secret(seed) => s\n        (\"The code is \" + s + \".\") ^0\n    elif not pegs.valid(s):\n        \"Type 4 colours, each 1 to 6, like 1234, or random.\" ^0\n        return\n    \"The rule: guess 1122, then the first code, in order, that fits every answer so far.\" ^0\n    \"  guess  code  answer             codes left\" ^0\n    pegs.solve(s) => rows\n    for k in [0:len(rows) - 1]:\n        rows[k] => row\n        (\"  \" + lpad(str(k + 1), 5) + \"  \" + row[0] + \"  \" + answer(row[1]) + lpad(str(row[2]), 13)) ^0\n    (\"Solved in \" + str(len(rows)) + \" guesses. Over all 1,296 codes this rule never needs more than 8: 6,508 guesses in all, 5.02 a code.\") ^0\n\ndef score_two():\n    plain(input(\"guess (4 colours 1 to 6)> \")) => g\n    if g == \"\":\n        \"Cancelled.\" ^0\n        return\n    plain(input(\"code (4 colours 1 to 6)> \")) => c\n    if c == \"\":\n        \"Cancelled.\" ^0\n        return\n    if not pegs.valid(g) or not pegs.valid(c):\n        \"Type 4 colours, each 1 to 6, like 1234.\" ^0\n        return\n    pegs.counts(g) => cg\n    pegs.counts(c) => cc\n    \"  colour  in guess  in code  in both\" ^0\n    0 => both\n    for k in [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]:\n        0 => a\n        0 => b\n        if k in cg:\n            cg[k] => a\n        if k in cc:\n            cc[k] => b\n        if a > 0 or b > 0:\n            a => m\n            if b < a:\n                b => m\n            both + m => both\n            (\"  \" + lpad(k, 6) + lpad(str(a), 10) + lpad(str(b), 9) + lpad(str(m), 9)) ^0\n    pegs.score(g, c) => r\n    (\"Colours in both: \" + str(both) + \". Right colour in the right place: \" + str(r[0]) + \" black. The rest, \" + str(both) + \" - \" + str(r[0]) + \": \" + str(r[1]) + \" white.\") ^0\n\n\"== Mastermind ==\" ^0\n\"Codes of 4 colours, each 1 to 6: black for right colour, right place; white for right colour, wrong place.\" ^0\nTrue => running\nwhile running:\n    \"\" ^0\n    \"1) play  2) watch the computer  3) score a guess  4) quit\" ^0\n    plain(input(\"choice> \")) => choice\n    if choice == \"1\":\n        play()\n    elif choice == \"2\":\n        watch()\n    elif choice == \"3\":\n        score_two()\n    elif choice == \"4\":\n        False => running\n    else:\n        \"Pick a number from 1 to 4.\" ^0\n\"Bye.\" ^0\n",
      "python": "import pegs\n\ndef plain(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 number(s, most):\n    if len(s) == 0 or len(s) > most:\n        return -1\n    n = 0\n    for c in s:\n        if not (c >= \"0\" and c <= \"9\"):\n            return -1\n        n = n * 10 + int(c)\n    return n\n\ndef lpad(s, n):\n    while len(s) < n:\n        s = \" \" + s\n    return s\n\ndef answer(r):\n    return str(r[0]) + \" black, \" + str(r[1]) + \" white\"\n\ndef still(n):\n    if n == 1:\n        return \"1 code still fits every answer.\"\n    return str(n) + \" codes still fit every answer.\"\n\ndef ask_seed():\n    while True:\n        a = plain(input(\"seed (0 to 999999)> \"))\n        if a == \"\":\n            return -1\n        n = number(a, 6)\n        if n >= 0:\n            return n\n        print(\"Type a whole number from 0 to 999999.\")\n\ndef play():\n    seed = ask_seed()\n    if seed == -1:\n        print(\"Cancelled.\")\n        return\n    code = pegs.secret(seed)\n    print(\"I have picked a code: 4 colours, each 1 to 6, repeats allowed. You have 10 guesses.\")\n    left = pegs.all_codes()\n    turn = 1\n    while turn <= 10:\n        g = plain(input(\"guess \" + str(turn) + \" (4 colours 1 to 6, ? for a hint)> \"))\n        if g == \"\":\n            print(\"You stopped. The code was \" + code + \".\")\n            return\n        if g == \"?\":\n            print(\"A code that fits every answer so far: \" + left[0] + \".\")\n        elif not pegs.valid(g):\n            print(\"Type 4 colours, each 1 to 6, like 1234.\")\n        else:\n            r = pegs.score(g, code)\n            fitted = False\n            for c in left:\n                if c == g:\n                    fitted = True\n            left = pegs.fits(left, g, r)\n            if r[0] == 4:\n                print(\"4 black: that is the code, in \" + str(turn) + \" guesses.\")\n                return\n            if fitted:\n                print(answer(r) + \". \" + still(len(left)))\n            else:\n                print(answer(r) + \". \" + still(len(left)) + \" (That guess could not have been the code: it did not fit an earlier answer.)\")\n            turn = turn + 1\n    print(\"No guesses left. The code was \" + code + \".\")\n\ndef watch():\n    s = plain(input(\"your code (4 colours 1 to 6), or random> \"))\n    if s == \"\":\n        print(\"Cancelled.\")\n        return\n    if s == \"random\":\n        seed = ask_seed()\n        if seed == -1:\n            print(\"Cancelled.\")\n            return\n        s = pegs.secret(seed)\n        print(\"The code is \" + s + \".\")\n    elif not pegs.valid(s):\n        print(\"Type 4 colours, each 1 to 6, like 1234, or random.\")\n        return\n    print(\"The rule: guess 1122, then the first code, in order, that fits every answer so far.\")\n    print(\"  guess  code  answer             codes left\")\n    rows = pegs.solve(s)\n    for k in range(0, len(rows)):\n        row = rows[k]\n        print(\"  \" + lpad(str(k + 1), 5) + \"  \" + row[0] + \"  \" + answer(row[1]) + lpad(str(row[2]), 13))\n    print(\"Solved in \" + str(len(rows)) + \" guesses. Over all 1,296 codes this rule never needs more than 8: 6,508 guesses in all, 5.02 a code.\")\n\ndef score_two():\n    g = plain(input(\"guess (4 colours 1 to 6)> \"))\n    if g == \"\":\n        print(\"Cancelled.\")\n        return\n    c = plain(input(\"code (4 colours 1 to 6)> \"))\n    if c == \"\":\n        print(\"Cancelled.\")\n        return\n    if not pegs.valid(g) or not pegs.valid(c):\n        print(\"Type 4 colours, each 1 to 6, like 1234.\")\n        return\n    cg = pegs.counts(g)\n    cc = pegs.counts(c)\n    print(\"  colour  in guess  in code  in both\")\n    both = 0\n    for k in [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]:\n        a = 0\n        b = 0\n        if k in cg:\n            a = cg[k]\n        if k in cc:\n            b = cc[k]\n        if a > 0 or b > 0:\n            m = a\n            if b < a:\n                m = b\n            both = both + m\n            print(\"  \" + lpad(k, 6) + lpad(str(a), 10) + lpad(str(b), 9) + lpad(str(m), 9))\n    r = pegs.score(g, c)\n    print(\"Colours in both: \" + str(both) + \". Right colour in the right place: \" + str(r[0]) + \" black. The rest, \" + str(both) + \" - \" + str(r[0]) + \": \" + str(r[1]) + \" white.\")\n\nprint(\"== Mastermind ==\")\nprint(\"Codes of 4 colours, each 1 to 6: black for right colour, right place; white for right colour, wrong place.\")\nrunning = True\nwhile running:\n    print(\"\")\n    print(\"1) play  2) watch the computer  3) score a guess  4) quit\")\n    choice = plain(input(\"choice> \"))\n    if choice == \"1\":\n        play()\n    elif choice == \"2\":\n        watch()\n    elif choice == \"3\":\n        score_two()\n    elif choice == \"4\":\n        running = False\n    else:\n        print(\"Pick a number from 1 to 4.\")\nprint(\"Bye.\")\n"
    },
    {
      "name": "pegs.eml",
      "eml": "# P100 Mastermind - codes of 4 colours, 1 to 6, repeats allowed: 1,296 of\n# them. A guess is answered with black (right colour, right place) and\n# white (right colour, wrong place), counted colour by colour with a dict\n# as in the corpus case char-frequency-table. The computer's rule: guess\n# 1122, then the first code, in order, that fits every answer so far.\n\ndef all_codes():\n    [] => out\n    for a in [1:6]:\n        for b in [1:6]:\n            for c in [1:6]:\n                for d in [1:6]:\n                    out + [str(a) + str(b) + str(c) + str(d)] => out\n    return out\n\ndef valid(s):\n    if len(s) != 4:\n        return False\n    for c in s:\n        if not (c >= \"1\" and c <= \"6\"):\n            return False\n    return True\n\ndef counts(s):\n    {} => out\n    for c in s:\n        if c in out:\n            out[c] + 1 => out[c]\n        else:\n            1 => out[c]\n    return out\n\ndef score(guess, code):\n    # [black, white]: black counts the places that match; every colour\n    # matches as often as it is in both, the fewer of the two counts, and\n    # white is what that leaves beyond black.\n    0 => black\n    for i in [0:3]:\n        if guess[i] == code[i]:\n            black + 1 => black\n    counts(guess) => g\n    counts(code) => k\n    0 => both\n    for c in g:\n        if c in k:\n            if g[c] < k[c]:\n                both + g[c] => both\n            else:\n                both + k[c] => both\n    return [black, both - black]\n\ndef fits(codes, guess, answer):\n    # the codes that would have given this answer to this guess\n    [] => out\n    for c in codes:\n        score(guess, c) => r\n        if r[0] == answer[0] and r[1] == answer[1]:\n            out + [c] => out\n    return out\n\ndef solve(code):\n    # [[guess, answer, codes still fitting], ...] until 4 black\n    all_codes() => left\n    \"1122\" => guess\n    [] => out\n    True => going\n    while going:\n        score(guess, code) => r\n        fits(left, guess, r) => left\n        out + [[guess, r, len(left)]] => out\n        if r[0] == 4:\n            False => going\n        else:\n            left[0] => guess\n    return out\n\ndef secret(seed):\n    # 4 colours from a linear congruential generator, top 16 bits\n    seed => x\n    \"\" => out\n    for i in [1:4]:\n        (1664525 * x + 1013904223) % 4294967296 => x\n        # x is below 2 ** 32, so the division is exact\n        out + str(int((x - x % 65536) / 65536) % 6 + 1) => out\n    return out\n",
      "python": "def all_codes():\n    out = []\n    for a in range(1, 7):\n        for b in range(1, 7):\n            for c in range(1, 7):\n                for d in range(1, 7):\n                    out = out + [str(a) + str(b) + str(c) + str(d)]\n    return out\n\ndef valid(s):\n    if len(s) != 4:\n        return False\n    for c in s:\n        if not (c >= \"1\" and c <= \"6\"):\n            return False\n    return True\n\ndef counts(s):\n    out = {}\n    for c in s:\n        if c in out:\n            out[c] = out[c] + 1\n        else:\n            out[c] = 1\n    return out\n\ndef score(guess, code):\n    black = 0\n    for i in range(0, 4):\n        if guess[i] == code[i]:\n            black = black + 1\n    g = counts(guess)\n    k = counts(code)\n    both = 0\n    for c in g:\n        if c in k:\n            if g[c] < k[c]:\n                both = both + g[c]\n            else:\n                both = both + k[c]\n    return [black, both - black]\n\ndef fits(codes, guess, answer):\n    out = []\n    for c in codes:\n        r = score(guess, c)\n        if r[0] == answer[0] and r[1] == answer[1]:\n            out = out + [c]\n    return out\n\ndef solve(code):\n    left = all_codes()\n    guess = \"1122\"\n    out = []\n    going = True\n    while going:\n        r = score(guess, code)\n        left = fits(left, guess, r)\n        out = out + [[guess, r, len(left)]]\n        if r[0] == 4:\n            going = False\n        else:\n            guess = left[0]\n    return out\n\ndef secret(seed):\n    x = seed\n    out = \"\"\n    for i in range(1, 5):\n        x = (1664525 * x + 1013904223) % 4294967296\n        out = out + str(int((x - x % 65536) / 65536) % 6 + 1)\n    return out\n"
    }
  ],
  "sessions": [
    {
      "name": "bad-input",
      "input": "0\nx\n1\nx\n\n1\n0\n123\n12345\n1237\nabcd\n1111\n1111\n1111\n1111\n1111\n1111\n1111\n1111\n1111\n1111\n2\n\n2\n777\n2\nrandom\n\n3\n12\n1234\n3\n\n3\n1234\n\n4\n",
      "screen": "== Mastermind ==\nCodes of 4 colours, each 1 to 6: black for right colour, right place; white for right colour, wrong place.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 0\nPick a number from 1 to 4.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> x\nPick a number from 1 to 4.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 1\nseed (0 to 999999)> x\nType a whole number from 0 to 999999.\nseed (0 to 999999)> \nCancelled.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 1\nseed (0 to 999999)> 0\nI have picked a code: 4 colours, each 1 to 6, repeats allowed. You have 10 guesses.\nguess 1 (4 colours 1 to 6, ? for a hint)> 123\nType 4 colours, each 1 to 6, like 1234.\nguess 1 (4 colours 1 to 6, ? for a hint)> 12345\nType 4 colours, each 1 to 6, like 1234.\nguess 1 (4 colours 1 to 6, ? for a hint)> 1237\nType 4 colours, each 1 to 6, like 1234.\nguess 1 (4 colours 1 to 6, ? for a hint)> abcd\nType 4 colours, each 1 to 6, like 1234.\nguess 1 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer.\nguess 2 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 3 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 4 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 5 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 6 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 7 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 8 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 9 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 10 (4 colours 1 to 6, ? for a hint)> 1111\n0 black, 0 white. 625 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nNo guesses left. The code was 3536.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 2\nyour code (4 colours 1 to 6), or random> \nCancelled.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 2\nyour code (4 colours 1 to 6), or random> 777\nType 4 colours, each 1 to 6, like 1234, or random.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 2\nyour code (4 colours 1 to 6), or random> random\nseed (0 to 999999)> \nCancelled.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 3\nguess (4 colours 1 to 6)> 12\ncode (4 colours 1 to 6)> 1234\nType 4 colours, each 1 to 6, like 1234.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 3\nguess (4 colours 1 to 6)> \nCancelled.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 3\nguess (4 colours 1 to 6)> 1234\ncode (4 colours 1 to 6)> \nCancelled.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 4\nBye.\n",
      "interpreter": "equal"
    },
    {
      "name": "basic",
      "input": "1\n7\n1122\n3344\n?\n1311\n?\n1511\n1\n42\n1234\n5566\n\n2\n3456\n2\nrandom\n7\n2\n6543\n3\n1234\n1325\n3\n1122\n2211\n3\n6666\n6616\n4\n",
      "screen": "== Mastermind ==\nCodes of 4 colours, each 1 to 6: black for right colour, right place; white for right colour, wrong place.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 1\nseed (0 to 999999)> 7\nI have picked a code: 4 colours, each 1 to 6, repeats allowed. You have 10 guesses.\nguess 1 (4 colours 1 to 6, ? for a hint)> 1122\n1 black, 1 white. 208 codes still fit every answer.\nguess 2 (4 colours 1 to 6, ? for a hint)> 3344\n0 black, 0 white. 56 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 3 (4 colours 1 to 6, ? for a hint)> ?\nA code that fits every answer so far: 1255.\nguess 3 (4 colours 1 to 6, ? for a hint)> 1311\n3 black, 0 white. 2 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 4 (4 colours 1 to 6, ? for a hint)> ?\nA code that fits every answer so far: 1511.\nguess 4 (4 colours 1 to 6, ? for a hint)> 1511\n4 black: that is the code, in 4 guesses.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 1\nseed (0 to 999999)> 42\nI have picked a code: 4 colours, each 1 to 6, repeats allowed. You have 10 guesses.\nguess 1 (4 colours 1 to 6, ? for a hint)> 1234\n1 black, 2 white. 132 codes still fit every answer.\nguess 2 (4 colours 1 to 6, ? for a hint)> 5566\n1 black, 0 white. 36 codes still fit every answer. (That guess could not have been the code: it did not fit an earlier answer.)\nguess 3 (4 colours 1 to 6, ? for a hint)> \nYou stopped. The code was 2436.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 2\nyour code (4 colours 1 to 6), or random> 3456\nThe rule: guess 1122, then the first code, in order, that fits every answer so far.\n  guess  code  answer             codes left\n      1  1122  0 black, 0 white          256\n      2  3333  1 black, 0 white          108\n      3  3444  2 black, 0 white           12\n      4  3455  3 black, 0 white            2\n      5  3456  4 black, 0 white            1\nSolved in 5 guesses. Over all 1,296 codes this rule never needs more than 8: 6,508 guesses in all, 5.02 a code.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 2\nyour code (4 colours 1 to 6), or random> random\nseed (0 to 999999)> 7\nThe code is 1511.\nThe rule: guess 1122, then the first code, in order, that fits every answer so far.\n  guess  code  answer             codes left\n      1  1122  1 black, 1 white          208\n      2  1233  1 black, 0 white           45\n      3  1411  3 black, 0 white            8\n      4  1414  2 black, 0 white            2\n      5  1511  4 black, 0 white            1\nSolved in 5 guesses. Over all 1,296 codes this rule never needs more than 8: 6,508 guesses in all, 5.02 a code.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 2\nyour code (4 colours 1 to 6), or random> 6543\nThe rule: guess 1122, then the first code, in order, that fits every answer so far.\n  guess  code  answer             codes left\n      1  1122  0 black, 0 white          256\n      2  3333  1 black, 0 white          108\n      3  3444  1 black, 1 white           24\n      4  5345  1 black, 2 white            6\n      5  5436  0 black, 4 white            2\n      6  6354  1 black, 3 white            1\n      7  6543  4 black, 0 white            1\nSolved in 7 guesses. Over all 1,296 codes this rule never needs more than 8: 6,508 guesses in all, 5.02 a code.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 3\nguess (4 colours 1 to 6)> 1234\ncode (4 colours 1 to 6)> 1325\n  colour  in guess  in code  in both\n       1         1        1        1\n       2         1        1        1\n       3         1        1        1\n       4         1        0        0\n       5         0        1        0\nColours in both: 3. Right colour in the right place: 1 black. The rest, 3 - 1: 2 white.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 3\nguess (4 colours 1 to 6)> 1122\ncode (4 colours 1 to 6)> 2211\n  colour  in guess  in code  in both\n       1         2        2        2\n       2         2        2        2\nColours in both: 4. Right colour in the right place: 0 black. The rest, 4 - 0: 4 white.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 3\nguess (4 colours 1 to 6)> 6666\ncode (4 colours 1 to 6)> 6616\n  colour  in guess  in code  in both\n       1         0        1        0\n       6         4        3        3\nColours in both: 3. Right colour in the right place: 3 black. The rest, 3 - 3: 0 white.\n\n1) play  2) watch the computer  3) score a guess  4) quit\nchoice> 4\nBye.\n",
      "interpreter": "equal"
    }
  ],
  "builtOn": [
    {
      "slug": "char-frequency-table",
      "caseId": "157-char-frequency-table",
      "title": "Counting with a dict, in first-appearance order"
    }
  ],
  "updated": "2026-10-15"
}
