- First attempt (without Python):
# This is the plan to solve Towers of Hanoi (based on magic!)
magically move(n-1, source, temp, target)
move( 1, source, target, temp)
magically move(n-1, temp, target, source)
- Turn into Python (The "magic" is recursion!):
def move(n, source, target, temp):
move(n-1, source, temp, target)
move( 1, source, target, temp)
move(n-1, temp, target, source)
move(2, 0, 1, 2) # Does not work -- infinite recursion
- Once again, with a base case:
def move(n, source, target, temp):
if (n == 1):
print((source, target), end="")
else:
move(n-1, source, temp, target)
move( 1, source, target, temp)
move(n-1, temp, target, source)
move(2, 0, 1, 2)
- Once more, with a nice wrapper:
def move(n, source, target, temp):
if (n == 1):
print((source, target), end="")
else:
move(n-1, source, temp, target)
move( 1, source, target, temp)
move(n-1, temp, target, source)
def hanoi(n):
print("Solving Towers of Hanoi with n =", n)
move(n, 0, 1, 2)
print()
hanoi(4)
- And again, printing call stack and recursion depth:
def move(n, source, target, temp, depth=0):
print((" " * 3 * depth), "move", n,
"from", source, "to", target, "via", temp)
if (n == 1):
print((" " * 3 * depth), (source, target))
else:
move(n-1, source, temp, target, depth+1)
move( 1, source, target, temp, depth+1)
move(n-1, temp, target, source, depth+1)
def hanoi(n):
print("Solving Towers of Hanoi with n =", n)
move(n, 0, 1, 2)
print()
hanoi(4)
- Iterative Towers of Hanoi (just to see it's possible):
def iterativeHanoi(n):
def f(k): return (k%3) if (n%2==0) else (-k%3)
return [(f(move & (move-1)),
f((move|(move-1))+1)) for move in range(1,1 << n)]
def recursiveHanoi(n, source=0, target=1, temp=2):
if (n == 1):
return [(source, target)]
else:
return (recursiveHanoi(n-1, source, temp, target) +
recursiveHanoi( 1, source, target, temp) +
recursiveHanoi(n-1, temp, target, source))
def compareIterativeAndRecursiveHanoi():
for n in range(1,10):
assert(iterativeHanoi(n) == recursiveHanoi(n))
print("iterative and recursive solutions match exactly in all tests!")
compareIterativeAndRecursiveHanoi()