def power(base, expt):
# This version allows for negative exponents
# It still assumes that expt is an integer, however.
if (expt == 0):
return 1
elif (expt < 0):
return 1.0/power(base,abs(expt))
else:
return base * power(base, expt-1)
print(power(2,5)) # 32
print(power(2,-5)) # 1/32 = 0.03125
1. fibonacci
A first attempt
def fib(n):
if (n < 2):
# Base case: fib(0) and fib(1) are both 1
return 1
else:
# Recursive case: fib(n) = fib(n-1) + fib(n-2)
return fib(n-1) + fib(n-2)
print([fib(n) for n in range(15)])
Once again, printing call stack using recursion depth:
def fib(n, depth=0):
print(" "*depth, "fib(", n, " )")
if (n < 2):
# Base case: fib(0) and fib(1) are both 1
return 1
else:
return fib(n-1, depth+1) + fib(n-2, depth+1)
fib(4)
Even better (printing result, too):
def fib(n, depth=0):
print(" "*depth, "fib(", n, " )")
if (n < 2):
result = 1
# Base case: fib(0) and fib(1) are both 1
print(" "*depth, "-->", result)
return result
else:
result = fib(n-1, depth+1) + fib(n-2, depth+1)
print(" "*depth, "-->", result)
return result
fib(4)
Finally, not duplicating code:
def fib(n, depth=0):
print(" "*depth, "fib(", n, " )")
if (n < 2):
result = 1
else:
result = fib(n-1, depth+1) + fib(n-2, depth+1)
print(" "*depth, "-->", result)
return result
fib(4)
Towers of Hanoi
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)
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()