{
  "id": "P042",
  "slug": "tower-of-hanoi",
  "key": "P042-tower-of-hanoi",
  "title": "Tower of Hanoi",
  "summary": "Move a tower of 1 to 8 disks from peg A to peg C, one disk at a time, never a larger disk on a smaller one. Every move is checked; a hint names the best next move, and the program can finish from any position in the fewest moves left - 2^n - 1 from the start.",
  "entry": "main.eml",
  "ui": "terminal",
  "readme": "# P042 - Tower of Hanoi\n\nMove a tower of 1 to 8 disks from peg A to peg C, one disk at a time, never\na larger disk on a smaller one. Every move is checked and the pegs are\ndrawn after it. A hint names the best next move, and the program can finish\nfrom wherever you are, always in the fewest moves left - 2^n - 1 from the\nstart.\n\n- `main.eml` - the menu, moves and their checks, hints, finishing, and the\n  game state\n- `hanoi.eml` - the pegs, the rule, the fewest moves from any position, and\n  the picture\n\nHow each part works:\n\n- The corpus case `tower-of-hanoi` solves the tower from the start by\n  recursion: move n - 1 disks out of the way, move the largest, move the\n  n - 1 back on top. Here the same recursion starts from any legal position:\n  to put disks 1 to k on a peg, if disk k is there already only the smaller\n  ones need moving; otherwise the smaller ones go to the third peg, disk k\n  moves, and the smaller ones come back on top of it. That this is the\n  fewest was checked against a breadth-first search over every position of\n  up to 7 disks (3,279 positions in all).\n- A hint is the first move of that sequence, with how many follow.\n- Only the top disk of a peg moves; a disk may go on an empty peg or on a\n  larger disk.\n\nWhat is checked: a move as two pegs, from and to (`AC`, `a c`, `A-C` or\n`A->C`), different, from a peg with a disk, not onto a smaller disk; 1 to 8\ndisks. An empty answer cancels.\n\nSessions: `sessions/basic.in` plays three disks, follows two hints and lets\nthe program finish - 7 moves, the fewest possible; then four disks, where\nthe first move goes to the wrong peg and the program finishes in 15 more, 16\nin all. `sessions/bad-input.in` gives menu choices 0 and x, moves AA, BC\nfrom the empty peg B, AX, A and ABC, a larger disk onto a smaller one, disk\ncounts 0, 9 and x, and a one-disk tower solved in one move, after which\nmoving, hints and finishing say it is done.\n\nBuilt on the verified corpus case `tower-of-hanoi` (the recursive solution:\ntwo recursive calls, each returning its own list of moves).\n",
  "modules": [
    {
      "name": "main.eml",
      "eml": "# P042 Tower of Hanoi: move the whole tower from peg A to peg C, one disk at\n# a time, never a larger disk on a smaller one. Ask for a hint, or let the\n# program finish from wherever you are - always in the fewest moves left.\nimport hanoi\n\n8 => most_disks\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 peg_of(c):\n    \"ABCabc\" => all\n    for i in [0:5]:\n        if all[i] == c:\n            return i % 3\n    return -1\n\ndef moves_text(n):\n    if n == 1:\n        return \"1 move\"\n    return str(n) + \" moves\"\n\ndef fewest(n):\n    # 2^n - 1, the fewest moves for a whole tower of n disks.\n    1 => p\n    for k in [1:n]:\n        p * 2 => p\n    return p - 1\n\ndef show(state):\n    for line in hanoi.picture(state[0], state[1]):\n        line ^0\n    (moves_text(state[2]) + \" made.\") ^0\n\ndef solved(state):\n    return len(state[0][2]) == state[1]\n\ndef move_text(m):\n    return hanoi.letters[m[0]] + \"->\" + hanoi.letters[m[1]]\n\ndef ask_move(state):\n    if solved(state):\n        \"The tower is already on C - start a new game to play again.\" ^0\n        return state\n    while True:\n        trim(input(\"move (from and to, like AC)> \")) => answer\n        if answer == \"\":\n            \"Cancelled.\" ^0\n            return state\n        \"\" => letters\n        for c in answer:\n            if c != \" \" and c != \"-\" and c != \">\":\n                letters + c => letters\n        if len(letters) != 2 or peg_of(letters[0]) == -1 or peg_of(letters[1]) == -1:\n            \"Type two pegs, from and to, like AC or B C.\" ^0\n        else:\n            peg_of(letters[0]) => f\n            peg_of(letters[1]) => t\n            hanoi.why_not(state[0], f, t) => why\n            if why != \"\":\n                why ^0\n            else:\n                [hanoi.moved(state[0], f, t), state[1], state[2] + 1] => state\n                show(state)\n                if solved(state):\n                    done(state)\n                return state\n\ndef done(state):\n    fewest(state[1]) => best\n    if state[2] == best:\n        (\"Solved in \" + moves_text(state[2]) + \" - the fewest possible, 2^\" + str(state[1]) + \" - 1.\") ^0\n    else:\n        (\"Solved in \" + moves_text(state[2]) + \"; the fewest possible is \" + str(best) + \", 2^\" + str(state[1]) + \" - 1.\") ^0\n\ndef finish(state):\n    if solved(state):\n        \"The tower is already on C.\" ^0\n        return state\n    hanoi.solution(state[0], state[1]) => moves\n    (\"The fewest moves from here: \" + str(len(moves)) + \".\") ^0\n    \"\" => line\n    0 => count\n    for m in moves:\n        if line != \"\":\n            line + \"  \" => line\n        line + move_text(m) => line\n        count + 1 => count\n        if count % 10 == 0:\n            (\"  \" + line) ^0\n            \"\" => line\n    if line != \"\":\n        (\"  \" + line) ^0\n    state[0] => pegs\n    for m in moves:\n        hanoi.moved(pegs, m[0], m[1]) => pegs\n    [pegs, state[1], state[2] + len(moves)] => state\n    show(state)\n    done(state)\n    return state\n\ndef new_game(state):\n    while True:\n        trim(input(\"disks (1 to \" + str(most_disks) + \")> \")) => answer\n        if answer == \"\":\n            \"Cancelled.\" ^0\n            return state\n        -1 => n\n        if len(answer) == 1 and answer[0] in \"0123456789\":\n            int(answer) => n\n        if n >= 1 and n <= most_disks:\n            [hanoi.start(n), n, 0] => state\n            (\"A tower of \" + str(n) + \" on A; the fewest moves to C are \" + str(fewest(n)) + \".\") ^0\n            show(state)\n            return state\n        (\"Type a number from 1 to \" + str(most_disks) + \".\") ^0\n\n\"== Tower of Hanoi ==\" ^0\n\"Move the tower from A to C, one disk at a time, never a larger disk on a smaller one.\" ^0\n[hanoi.start(3), 3, 0] => state\nshow(state)\nTrue => running\nwhile running:\n    \"\" ^0\n    \"1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\" ^0\n    trim(input(\"choice> \")) => choice\n    if choice == \"1\":\n        ask_move(state) => state\n    elif choice == \"2\":\n        if solved(state):\n            \"The tower is already on C.\" ^0\n        else:\n            hanoi.solution(state[0], state[1]) => moves\n            (\"Hint: \" + move_text(moves[0]) + \" - then \" + str(len(moves) - 1) + \" more, at the fewest.\") ^0\n    elif choice == \"3\":\n        finish(state) => state\n    elif choice == \"4\":\n        new_game(state) => state\n    elif choice == \"5\":\n        show(state)\n    elif choice == \"6\":\n        False => running\n    else:\n        \"Pick a number from 1 to 6.\" ^0\n\"Bye.\" ^0\n",
      "python": "import hanoi\nmost_disks = 8\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 peg_of(c):\n    all = \"ABCabc\"\n    for i in range(0, 6):\n        if all[i] == c:\n            return i % 3\n    return -1\n\ndef moves_text(n):\n    if n == 1:\n        return \"1 move\"\n    return str(n) + \" moves\"\n\ndef fewest(n):\n    p = 1\n    for k in range(1, n+1):\n        p = p * 2\n    return p - 1\n\ndef show(state):\n    for line in hanoi.picture(state[0], state[1]):\n        print(line)\n    print(moves_text(state[2]) + \" made.\")\n\ndef solved(state):\n    return len(state[0][2]) == state[1]\n\ndef move_text(m):\n    return hanoi.letters[m[0]] + \"->\" + hanoi.letters[m[1]]\n\ndef ask_move(state):\n    if solved(state):\n        print(\"The tower is already on C - start a new game to play again.\")\n        return state\n    while True:\n        answer = trim(input(\"move (from and to, like AC)> \"))\n        if answer == \"\":\n            print(\"Cancelled.\")\n            return state\n        letters = \"\"\n        for c in answer:\n            if c != \" \" and c != \"-\" and c != \">\":\n                letters = letters + c\n        if len(letters) != 2 or peg_of(letters[0]) == -1 or peg_of(letters[1]) == -1:\n            print(\"Type two pegs, from and to, like AC or B C.\")\n        else:\n            f = peg_of(letters[0])\n            t = peg_of(letters[1])\n            why = hanoi.why_not(state[0], f, t)\n            if why != \"\":\n                print(why)\n            else:\n                state = [hanoi.moved(state[0], f, t), state[1], state[2] + 1]\n                show(state)\n                if solved(state):\n                    done(state)\n                return state\n\ndef done(state):\n    best = fewest(state[1])\n    if state[2] == best:\n        print(\"Solved in \" + moves_text(state[2]) + \" - the fewest possible, 2^\" + str(state[1]) + \" - 1.\")\n    else:\n        print(\"Solved in \" + moves_text(state[2]) + \"; the fewest possible is \" + str(best) + \", 2^\" + str(state[1]) + \" - 1.\")\n\ndef finish(state):\n    if solved(state):\n        print(\"The tower is already on C.\")\n        return state\n    moves = hanoi.solution(state[0], state[1])\n    print(\"The fewest moves from here: \" + str(len(moves)) + \".\")\n    line = \"\"\n    count = 0\n    for m in moves:\n        if line != \"\":\n            line = line + \"  \"\n        line = line + move_text(m)\n        count = count + 1\n        if count % 10 == 0:\n            print(\"  \" + line)\n            line = \"\"\n    if line != \"\":\n        print(\"  \" + line)\n    pegs = state[0]\n    for m in moves:\n        pegs = hanoi.moved(pegs, m[0], m[1])\n    state = [pegs, state[1], state[2] + len(moves)]\n    show(state)\n    done(state)\n    return state\n\ndef new_game(state):\n    while True:\n        answer = trim(input(\"disks (1 to \" + str(most_disks) + \")> \"))\n        if answer == \"\":\n            print(\"Cancelled.\")\n            return state\n        n = -1\n        if len(answer) == 1 and answer[0] in \"0123456789\":\n            n = int(answer)\n        if n >= 1 and n <= most_disks:\n            state = [hanoi.start(n), n, 0]\n            print(\"A tower of \" + str(n) + \" on A; the fewest moves to C are \" + str(fewest(n)) + \".\")\n            show(state)\n            return state\n        print(\"Type a number from 1 to \" + str(most_disks) + \".\")\n\nprint(\"== Tower of Hanoi ==\")\nprint(\"Move the tower from A to C, one disk at a time, never a larger disk on a smaller one.\")\nstate = [hanoi.start(3), 3, 0]\nshow(state)\nrunning = True\nwhile running:\n    print(\"\")\n    print(\"1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\")\n    choice = trim(input(\"choice> \"))\n    if choice == \"1\":\n        state = ask_move(state)\n    elif choice == \"2\":\n        if solved(state):\n            print(\"The tower is already on C.\")\n        else:\n            moves = hanoi.solution(state[0], state[1])\n            print(\"Hint: \" + move_text(moves[0]) + \" - then \" + str(len(moves) - 1) + \" more, at the fewest.\")\n    elif choice == \"3\":\n        state = finish(state)\n    elif choice == \"4\":\n        state = new_game(state)\n    elif choice == \"5\":\n        show(state)\n    elif choice == \"6\":\n        running = False\n    else:\n        print(\"Pick a number from 1 to 6.\")\nprint(\"Bye.\")\n"
    },
    {
      "name": "hanoi.eml",
      "eml": "# P042 Tower of Hanoi - the pegs, the rule and the fewest moves. Pegs are\n# 0, 1, 2 (shown as A, B, C); each is a list of disk sizes from the bottom\n# up, so its last disk is the top one.\n\n\"ABC\" => letters\n\ndef start(n):\n    [] => a\n    for k in [0:n - 1]:\n        a + [n - k] => a\n    return [a, [], []]\n\ndef why_not(pegs, f, t):\n    # \"\" if the top disk of peg f may move to peg t, otherwise the reason.\n    if f == t:\n        return \"A disk has to move to another peg.\"\n    if len(pegs[f]) == 0:\n        return \"Peg \" + letters[f] + \" is empty.\"\n    pegs[f][len(pegs[f]) - 1] => disk\n    if len(pegs[t]) > 0 and pegs[t][len(pegs[t]) - 1] < disk:\n        return \"Disk \" + str(disk) + \" cannot go on disk \" + str(pegs[t][len(pegs[t]) - 1]) + \".\"\n    return \"\"\n\ndef moved(pegs, f, t):\n    # The pegs after moving the top disk of f to t (the move is legal).\n    pegs[f][len(pegs[f]) - 1] => disk\n    [] => out\n    for p in [0:2]:\n        if p == f:\n            out + [pegs[p][0:len(pegs[p]) - 1]] => out\n        elif p == t:\n            out + [pegs[p] + [disk]] => out\n        else:\n            out + [pegs[p]] => out\n    return out\n\ndef where(pegs, n):\n    # where[k] is the peg disk k is on (index 0 unused).\n    [0] * (n + 1) => at\n    for p in [0:2]:\n        for disk in pegs[p]:\n            p => at[disk]\n    return at\n\ndef gather(at, k, target):\n    # The fewest moves that put disks 1 to k on the target peg, from any\n    # legal position: if disk k is there already, only the smaller ones need\n    # moving; otherwise the smaller ones go to the third peg, disk k moves,\n    # and the smaller ones come back on top of it. at is changed to match.\n    if k == 0:\n        return []\n    if at[k] == target:\n        return gather(at, k - 1, target)\n    3 - at[k] - target => other\n    gather(at, k - 1, other) => before\n    [[at[k], target]] => middle\n    target => at[k]\n    gather(at, k - 1, target) => after\n    return before + middle + after\n\ndef solution(pegs, n):\n    # The fewest moves from here to every disk on peg C.\n    return gather(where(pegs, n), n, 2)\n\ndef picture(pegs, n):\n    2 * n + 1 => width\n    [] => lines\n    n - 1 => level\n    while level >= 0:\n        \"\" => line\n        for p in [0:2]:\n            \"|\" => s\n            if level < len(pegs[p]):\n                pegs[p][level] => disk\n                \"[\" + \"=\" * (2 * disk - 1) + \"]\" => s\n            \" \" * int((width - len(s)) / 2) => side\n            line + \" \" + side + s + side + \" \" => line\n        len(line) => j\n        while j > 0 and line[j - 1] == \" \":\n            j - 1 => j\n        lines + [line[0:j]] => lines\n        level - 1 => level\n    \"\" => base\n    \"\" => names\n    for p in [0:2]:\n        base + \"-\" + \"-\" * width + \"-\" => base\n        names + \" \" + \" \" * n + letters[p] + \" \" * n + \" \" => names\n    lines + [base] => lines\n    len(names) => j\n    while j > 0 and names[j - 1] == \" \":\n        j - 1 => j\n    lines + [names[0:j]] => lines\n    return lines\n",
      "python": "letters = \"ABC\"\n\ndef start(n):\n    a = []\n    for k in range(0, n):\n        a = a + [n - k]\n    return [a, [], []]\n\ndef why_not(pegs, f, t):\n    if f == t:\n        return \"A disk has to move to another peg.\"\n    if len(pegs[f]) == 0:\n        return \"Peg \" + letters[f] + \" is empty.\"\n    disk = pegs[f][len(pegs[f]) - 1]\n    if len(pegs[t]) > 0 and pegs[t][len(pegs[t]) - 1] < disk:\n        return \"Disk \" + str(disk) + \" cannot go on disk \" + str(pegs[t][len(pegs[t]) - 1]) + \".\"\n    return \"\"\n\ndef moved(pegs, f, t):\n    disk = pegs[f][len(pegs[f]) - 1]\n    out = []\n    for p in range(0, 3):\n        if p == f:\n            out = out + [pegs[p][0:len(pegs[p]) - 1]]\n        elif p == t:\n            out = out + [pegs[p] + [disk]]\n        else:\n            out = out + [pegs[p]]\n    return out\n\ndef where(pegs, n):\n    at = [0] * (n + 1)\n    for p in range(0, 3):\n        for disk in pegs[p]:\n            at[disk] = p\n    return at\n\ndef gather(at, k, target):\n    if k == 0:\n        return []\n    if at[k] == target:\n        return gather(at, k - 1, target)\n    other = 3 - at[k] - target\n    before = gather(at, k - 1, other)\n    middle = [[at[k], target]]\n    at[k] = target\n    after = gather(at, k - 1, target)\n    return before + middle + after\n\ndef solution(pegs, n):\n    return gather(where(pegs, n), n, 2)\n\ndef picture(pegs, n):\n    width = 2 * n + 1\n    lines = []\n    level = n - 1\n    while level >= 0:\n        line = \"\"\n        for p in range(0, 3):\n            s = \"|\"\n            if level < len(pegs[p]):\n                disk = pegs[p][level]\n                s = \"[\" + \"=\" * (2 * disk - 1) + \"]\"\n            side = \" \" * int((width - len(s)) / 2)\n            line = line + \" \" + side + s + side + \" \"\n        j = len(line)\n        while j > 0 and line[j - 1] == \" \":\n            j = j - 1\n        lines = lines + [line[0:j]]\n        level = level - 1\n    base = \"\"\n    names = \"\"\n    for p in range(0, 3):\n        base = base + \"-\" + \"-\" * width + \"-\"\n        names = names + \" \" + \" \" * n + letters[p] + \" \" * n + \" \"\n    lines = lines + [base]\n    j = len(names)\n    while j > 0 and names[j - 1] == \" \":\n        j = j - 1\n    lines = lines + [names[0:j]]\n    return lines\n"
    }
  ],
  "sessions": [
    {
      "name": "bad-input",
      "input": "0\nx\n1\nAA\nBC\nAX\nA\nABC\n\n1\nAC\n1\nAC\nAB\n4\n0\n9\nx\n\n4\n1\n2\n1\nAC\n1\n2\n3\n5\n6\n",
      "screen": "== Tower of Hanoi ==\nMove the tower from A to C, one disk at a time, never a larger disk on a smaller one.\n   [=]       |        |\n  [===]      |        |\n [=====]     |        |\n---------------------------\n    A        B        C\n0 moves made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 0\nPick a number from 1 to 6.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> x\nPick a number from 1 to 6.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> AA\nA disk has to move to another peg.\nmove (from and to, like AC)> BC\nPeg B is empty.\nmove (from and to, like AC)> AX\nType two pegs, from and to, like AC or B C.\nmove (from and to, like AC)> A\nType two pegs, from and to, like AC or B C.\nmove (from and to, like AC)> ABC\nType two pegs, from and to, like AC or B C.\nmove (from and to, like AC)> \nCancelled.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> AC\n    |        |        |\n  [===]      |        |\n [=====]     |       [=]\n---------------------------\n    A        B        C\n1 move made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> AC\nDisk 2 cannot go on disk 1.\nmove (from and to, like AC)> AB\n    |        |        |\n    |        |        |\n [=====]   [===]     [=]\n---------------------------\n    A        B        C\n2 moves made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 4\ndisks (1 to 8)> 0\nType a number from 1 to 8.\ndisks (1 to 8)> 9\nType a number from 1 to 8.\ndisks (1 to 8)> x\nType a number from 1 to 8.\ndisks (1 to 8)> \nCancelled.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 4\ndisks (1 to 8)> 1\nA tower of 1 on A; the fewest moves to C are 1.\n [=]   |    |\n---------------\n  A    B    C\n0 moves made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 2\nHint: A->C - then 0 more, at the fewest.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> AC\n  |    |   [=]\n---------------\n  A    B    C\n1 move made.\nSolved in 1 move - the fewest possible, 2^1 - 1.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nThe tower is already on C - start a new game to play again.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 2\nThe tower is already on C.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 3\nThe tower is already on C.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 5\n  |    |   [=]\n---------------\n  A    B    C\n1 move made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 6\nBye.\n",
      "interpreter": "equal"
    },
    {
      "name": "basic",
      "input": "1\nAC\n1\nAB\n2\n1\nc b\n1\nA-C\n2\n3\n4\n4\n1\nAC\n2\n3\n6\n",
      "screen": "== Tower of Hanoi ==\nMove the tower from A to C, one disk at a time, never a larger disk on a smaller one.\n   [=]       |        |\n  [===]      |        |\n [=====]     |        |\n---------------------------\n    A        B        C\n0 moves made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> AC\n    |        |        |\n  [===]      |        |\n [=====]     |       [=]\n---------------------------\n    A        B        C\n1 move made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> AB\n    |        |        |\n    |        |        |\n [=====]   [===]     [=]\n---------------------------\n    A        B        C\n2 moves made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 2\nHint: C->B - then 4 more, at the fewest.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> c b\n    |        |        |\n    |       [=]       |\n [=====]   [===]      |\n---------------------------\n    A        B        C\n3 moves made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> A-C\n    |        |        |\n    |       [=]       |\n    |      [===]   [=====]\n---------------------------\n    A        B        C\n4 moves made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 2\nHint: B->A - then 2 more, at the fewest.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 3\nThe fewest moves from here: 3.\n  B->A  B->C  A->C\n    |        |       [=]\n    |        |      [===]\n    |        |     [=====]\n---------------------------\n    A        B        C\n7 moves made.\nSolved in 7 moves - the fewest possible, 2^3 - 1.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 4\ndisks (1 to 8)> 4\nA tower of 4 on A; the fewest moves to C are 15.\n    [=]         |          |\n   [===]        |          |\n  [=====]       |          |\n [=======]      |          |\n---------------------------------\n     A          B          C\n0 moves made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 1\nmove (from and to, like AC)> AC\n     |          |          |\n   [===]        |          |\n  [=====]       |          |\n [=======]      |         [=]\n---------------------------------\n     A          B          C\n1 move made.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 2\nHint: C->B - then 14 more, at the fewest.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 3\nThe fewest moves from here: 15.\n  C->B  A->C  B->C  A->B  C->A  C->B  A->B  A->C  B->C  B->A\n  C->A  B->C  A->B  A->C  B->C\n     |          |         [=]\n     |          |        [===]\n     |          |       [=====]\n     |          |      [=======]\n---------------------------------\n     A          B          C\n16 moves made.\nSolved in 16 moves; the fewest possible is 15, 2^4 - 1.\n\n1) move  2) hint  3) finish for me  4) new game  5) show  6) quit\nchoice> 6\nBye.\n",
      "interpreter": "equal"
    }
  ],
  "builtOn": [
    {
      "slug": "tower-of-hanoi",
      "caseId": "077-tower-of-hanoi",
      "title": "Tower of Hanoi"
    }
  ],
  "updated": "2026-10-10"
}
