09-Recursion 4pp
09-Recursion 4pp
)
def factorial(n):
if n == 0 fact = 1
n! = 1 i = 1
while i <= n:
if n > 0 fact *= i # fact = fact * i
n! = n x (n-1) x (n-2) x ... x1 i += 1 # i = i + 1
return fact
factorial(3)
3 * factorial(2) 3 * factorial(2)
2 * factorial(1) 2 * factorial(1)
factorial(3) factorial(3)
1 * factorial(0)
def factorial(n): def factorial(n):
if n == 0: if n == 0:
return 1 return 1
else: else:
return n * factorial(n-1) return n * factorial(n-1)
3 * factorial(2) 3 * factorial(2)
2 * factorial(1) 2 * factorial(1)
factorial(3) factorial(3)
1 * factorial(0) 1 * 1
1
3 * factorial(2) 3 * 2
2 * 1
factorial(3) factorial(3)
Reversing a List (recursively)
factorial(3)
reverse(“d”) = “d”
reverse(“rd”) = “dr”
Reversing a List (recursively) Reversing a List (recursively)
reverse(“ward”) = “draw”
def reverse(s):
if len(s) == 1:
return s
else:
return reverse(s[1:]) + s[0]
# Write an iterative function that takes as input a # Write a recursive function that takes as input a
# non-negative integer “n” and returns the sum of the # non-negative integer “n” and returns the sum of the
# first “n” integers: sum(5) returns 1+2+3+4+5 # first “n” integers: sum(5) returns 1+2+3+4+5
# Write a Python function perfect_square that takes a # Write a recursive version of perfect_square
# single parameter and returns True if this parameter is
# a perfect square and False otherwise def ps(x,i=0):
from math import sqrt if i > sqrt(x):
return False
def perfect_square(x): else:
i = 0 return i*i==x or ps(x,i+1) # short-circuit
while i <= sqrt(x):
if i*i == x: ps(4)
return True
i = i + 1
return False
# Write a recursive version of perfect_square # Write a recursive version of perfect_square
fib(2) fib(3) 2
def fib(n): def fib(n):
if n == 1: if n == 1:
return 0 1 1 return 0
elif n == 2: elif n == 2:
return 1 return 1
else: else:
return fib(n-2) + fib(n-1) return fib(n-2) + fib(n-1)
# Tree recursion: count partitions # Tree recursion: count partitions
cp(6,4) cp(6,4)
1 + 1 + 1 + 1 + 1 + 1 # don’t use 4 1 + 1 + 1 + 1 + 1 + 1 # don’t use 4: cp(6,3)
1 + 1 + 1 + 1 + 2 1 + 1 + 1 + 1 + 2
1 + 1 + 2 + 2 1 + 1 + 2 + 2
2 + 2 + 2 2 + 2 + 2
1 + 1 + 1 + 3 1 + 1 + 1 + 3
1 + 2 + 3 1 + 2 + 3
3 + 3 3 + 3
1 + 1 + 4 1 + 1 + 4
2 + 4 # use 4 2 + 4 # use 4: cp(6-4,4)
# Tree recursion: count partitions # Tree recursion: partitions
# mutual recursion: Luhn sum (check sum) # mutual recursion: Luhn sum (check sum)
# mutual recursion: Luhn sum (check sum) # mutual recursion: Luhn sum (check sum)
7 9 9 2 7 3 9 8 7 1 3 # acct number 7 9 9 2 7 3 9 8 7 1 3
18 4 6 16 2 # double every other 18 4 6 16 2
9 4 6 7 2 # sum digits > 10 9 4 6 7 2
7 +9 +9 +4 +7 +6 +9 +7 +7 +2 +3 = 70 # sum 7 +9 +9 +4 +7 +6 +9 +7 +7 +2 +3 = 70
7 9 9 2 7 3 9 8 7 1 3 7 9 9 2 7 3 9 8 7 1 3
18 4 6 16 2 18 4 6 16 2
9 4 6 7 2 9 4 6 7 2
7 +9 +9 +4 +7 +6 +9 +7 +7 +2 +3 = 70 7 +9 +9 +4 +7 +6 +9 +7 +7 +2 +3 = 70
luhn_sum(79927398713) luhn_sum(79927398713)
luhn_sum2(7992739871) + 3 luhn_sum2(7992739871) + 3
luhn_sum(799273987) + sum_dig(2*1)
# mutual recursion: Luhn sum (check sum) # mutual recursion: Luhn sum (check sum)
7 9 9 2 7 3 9 8 7 1 3 7 9 9 2 7 3 9 8 7 1 3
18 4 6 16 2 18 4 6 16 2
9 4 6 7 2 9 4 6 7 2
7 +9 +9 +4 +7 +6 +9 +7 +7 +2 +3 = 70 7 +9 +9 +4 +7 +6 +9 +7 +7 +2 +3 = 70
luhn_sum(79927398713) luhn_sum(79927398713)
luhn_sum2(7992739871) + 3 luhn_sum2(7992739871) + 3
luhn_sum(799273987) + sum_dig(2*1) luhn_sum(799273987) + sum_dig(2*1)
luhn_sum2(79927398) + 7 luhn_sum2(79927398) + 7
luhn_sum(7992739) + sum_dig(2*8)
def split(n): def luhn_sum(n):
# Split a positive integer into all but its last digit and if n < 10:
# its last digit return n
# split(123) —> (123 // 10 = 12, 123 % 10 = 3) else:
return n // 10, n % 10 a, b = split(n)
return luhn_sum2(a) + b
def sum_digits(n):
# Return the sum of the digits of positive integer n def luhn_sum2(n):
if n < 10: a, b = split(n)
return n d = sum_digits(2 * b)
else: if n < 10:
a, b = split(n) return d
return sum_digits(a) + b else:
return luhn_sum(a) + d
http://haubergs.com/hanoi
1 2 3
Towers of Hanoi Towers of Hanoi
n = 1: move disk from post 1 to post 2 n = 2: move disks from post 1 to post 2
1 2 3 1 2 3
n = 2: move disks from post 1 to post 2 n = 2: move disks from post 1 to post 2
1 2 3 1 2 3
Towers of Hanoi Towers of Hanoi
n = 2: move disks from post 1 to post 2 n = 3: move disks from post 1 to post 2
1
2
3
1 2 3 1 2 3
1 1
3 2 3 2
1 2 3 1 2 3
Towers of Hanoi
hanoi(3,1,2) # move 3 disks from post 1 to 2
n = 3: move disks 1&2 from post 3 to 2
1 1
2 2
3 3
1 2 3 1 2 3
hanoi(3,1,2) # move 3 disks from post 1 to 2 hanoi(3,1,2) # move 3 disks from post 1 to 2
hanoi(2,1,3) # move 2 disks from post 1 to 3 hanoi(2,1,3) # move 2 disks from post 1 to 3
move(3,1,2) # move disk 3 from post 1 to 2
1 1
3 2 3 2
1 2 3 1 2 3
hanoi(3,1,2) # move 3 disks from post 1 to 2
hanoi(2,1,3) # move 2 disks from post 1 to 3
move(3,1,2) # move disk 3 from post 1 to 2
hanoi(2,3,2) # move 2 disks from post 3 to 2
1
2
3
1 2 3
1 2 3
def move_disk(disk_number, from_peg, to_peg): def move_disk(disk_number, from_peg, to_peg):
print("Move disk " + str(disk_number) + " from peg " \ print("Move disk " + str(disk_number) + " from peg " \
+ str(from_peg) + " to peg " + str(to_peg) + ".") + str(from_peg) + " to peg " + str(to_peg) + ".")
hanoi(3,1,2) hanoi(3,1,2)
hanoi(2,1,3)
move_disk(3,1,2)
hanoi(2,3,2)
1 1
2 2
3 3
1 2 3 1 2 3
hanoi(3,1,2) hanoi(3,1,2)
hanoi(2,1,3) hanoi(2,1,3)
hanoi(1,1,2) hanoi(1,1,2)
move_disk(2,1,3) move_disk(2,1,3)
hanoi(1,2,3) hanoi(1,2,3)
move_disk(3,1,2) move_disk(3,1,2)
hanoi(2,3,2) hanoi(2,3,2)
1
2 2
3 3 1
1 2 3 1 2 3
def solve_hanoi(n, start_peg, end_peg): def solve_hanoi(n, start_peg, end_peg):
if n == 1: if n == 1:
move_disk(n, start_peg, end_peg) move_disk(n, start_peg, end_peg)
else: else:
spare_peg = 6 - start_peg - end_peg spare_peg = 6 - start_peg - end_peg
solve_hanoi(n - 1, start_peg, spare_peg) solve_hanoi(n - 1, start_peg, spare_peg)
move_disk(n, start_peg, end_peg) move_disk(n, start_peg, end_peg)
solve_hanoi(n - 1, spare_peg, end_peg) solve_hanoi(n - 1, spare_peg, end_peg)
hanoi(3,1,2) hanoi(3,1,2)
hanoi(2,1,3) hanoi(2,1,3)
hanoi(1,1,2) hanoi(1,1,2)
move_disk(2,1,3) move_disk(2,1,3)
hanoi(1,2,3) hanoi(1,2,3)
move_disk(3,1,2) move_disk(3,1,2)
hanoi(2,3,2) hanoi(2,3,2)
1
3 1 2 3 2
1 2 3 1 2 3
hanoi(3,1,2) hanoi(3,1,2)
hanoi(2,1,3) hanoi(2,1,3)
hanoi(1,1,2) hanoi(1,1,2)
move_disk(2,1,3) move_disk(2,1,3)
hanoi(1,2,3) hanoi(1,2,3)
move_disk(3,1,2) move_disk(3,1,2)
hanoi(2,3,2) hanoi(2,3,2)
hanoi(1,3,1)
move_disk(2,3,2)
hanoi(1,1,2)
1 1
3 2 3 2
1 2 3 1 2 3
def solve_hanoi(n, start_peg, end_peg): def solve_hanoi(n, start_peg, end_peg):
if n == 1: if n == 1:
move_disk(n, start_peg, end_peg) move_disk(n, start_peg, end_peg)
else: else:
spare_peg = 6 - start_peg - end_peg spare_peg = 6 - start_peg - end_peg
solve_hanoi(n - 1, start_peg, spare_peg) solve_hanoi(n - 1, start_peg, spare_peg)
move_disk(n, start_peg, end_peg) move_disk(n, start_peg, end_peg)
solve_hanoi(n - 1, spare_peg, end_peg) solve_hanoi(n - 1, spare_peg, end_peg)
hanoi(3,1,2) hanoi(3,1,2)
hanoi(2,1,3) hanoi(2,1,3)
hanoi(1,1,2) hanoi(1,1,2)
move_disk(2,1,3) move_disk(2,1,3)
hanoi(1,2,3) hanoi(1,2,3)
move_disk(3,1,2) move_disk(3,1,2)
hanoi(2,3,2) hanoi(2,3,2)
hanoi(1,3,1) hanoi(1,3,1)
move_disk(2,3,2) move_disk(2,3,2)
hanoi(1,1,2) hanoi(1,1,2)
2
1 3 2 1 3
1 2 3 1 2 3
hanoi(3,1,2) hanoi(3,1,2)
hanoi(2,1,3) hanoi(2,1,3)
hanoi(1,1,2) hanoi(1,1,2)
move_disk(2,1,3) move_disk(2,1,3)
hanoi(1,2,3) hanoi(1,2,3)
move_disk(3,1,2) move_disk(3,1,2)
hanoi(2,3,2) hanoi(2,3,2)
hanoi(1,3,1) hanoi(1,3,1)
move_disk(2,3,2) move_disk(2,3,2)
hanoi(1,1,2) hanoi(1,1,2)
1 1
2 2
3 3
1 2 3 1 2 3
discs moves discs moves
1 1 1 1
2 3 2 3
3 3 7
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
… …
64 64