N=
Tap a rod to pick up a disk β€” or press AI Solve
⚠ BFS / DFS / A* are limited to N ≀ 8. Use Recursive for larger N.
Speed Med
h(n) heuristic
h=0/N=0
0
Moves
7
Optimal
0
Nodes
0.0s
Time
Result

Tower of Hanoi is a classic AI search problem. Each game state is a node in a 3α΄Ί state graph. Algorithms explore this graph from the initial state to the goal, with different trade-offs in time, memory, and solution quality.

State space
27
Optimal moves
7
Max branching
≀ 6
Depth
7
// Recursive Divide & Conquer β€” provably minimal
function hanoi(n, from, to, via) {
  if (n === 0) return;
  hanoi(n-1, from, via, to); // move n-1 disks to aux
  move(disk[n]: from β†’ to);    // move largest disk
  hanoi(n-1, via, to, from); // move n-1 to goal
} // Moves: 2βΏβˆ’1 Β· Time: O(2ⁿ) Β· Space: O(n)

BFS uses a FIFO queue to explore all states at depth d before d+1. Guarantees the shortest-path (optimal) solution, but stores the entire frontier in memory β€” O(3α΄Ί) space for Hanoi.

Time
O(3ⁿ)
Space
O(3ⁿ)
Complete?
Yes
Optimal?
Yes
queue ← [start]; visited ← {start}
while queue β‰  βˆ…:
  s ← queue.dequeue() // FIFO β€” level by level
  if s == goal: return path(s)
  for s' in expand(s):
    if s' βˆ‰ visited: visited βˆͺ= s'; queue.add(s')

DFS uses a LIFO stack, diving as deep as possible before backtracking. Memory-efficient at O(n) stack depth, but may find a sub-optimal path depending on the order successors are explored.

Time
O(3ⁿ)
Space
O(n)
Complete?
Yes*
Optimal?
No
stack ← [start]; visited ← {start}
while stack β‰  βˆ…:
  s ← stack.pop() // LIFO β€” deepest branch first
  if s == goal: return path(s)
  for s' in expand(s):
    if s' βˆ‰ visited: visited βˆͺ= s'; stack.push(s')

A* uses f(n)=g(n)+h(n) to guide the search. g(n) = cost so far (moves made). h(n) = admissible heuristic: disks not yet correctly stacked from the bottom of Rod C. With admissible h, A* is optimally efficient.

g(n)
Moves made
h(n)
Admissible βœ“
f(n)
g + h
Optimal?
Yes
// h(n) = N βˆ’ (disks correctly stacked at bottom of C)
open ← MinHeap(start, f = 0 + h(start))
while open β‰  βˆ…:
  n ← open.pop_min_f()
  if n == goal: return path
  for m in expand(n):
    g' ← n.g+1; if g' < g[m]: open.push(m, g'+h(m))
State
3-tuple (A,B,C) β€” each rod = ordered stack, largest disk at bottom
Initial
(⟨N..1⟩, ⟨⟩, ⟨⟩) β€” all N disks on Rod A
Goal
(⟨⟩, ⟨⟩, ⟨N..1⟩) β€” all N disks on Rod C
Actions
Move(i→j): top of rod i to rod j, if top[i] < top[j] or j is empty
Cost
Uniform β€” each legal move costs exactly 1
|States|
3α΄Ί reachable states (e.g. 59,049 for N=10)
Live State
Rod A
β€”
Rod B
β€”
Rod C
β€”
AlgorithmTimeSpaceMovesOptimal
RecursiveO(2ⁿ)O(n)2βΏβˆ’1Yes βœ“
BFSO(3ⁿ)O(3ⁿ)2βΏβˆ’1Yes βœ“
DFSO(3ⁿ)O(n)variesNo βœ—
A*O(3ⁿ)*O(3ⁿ)2βΏβˆ’1Yes βœ“

* A* explores fewer nodes than BFS thanks to the heuristic, but worst-case is still O(3ⁿ). Recursive is uniquely efficient: O(2ⁿ) time with only O(n) stack space β€” the gold standard.

Move Log 0 moves
No moves yet.
Tap a rod or hit AI Solve.