Recursion: concepts, examples, and makeChange

Post on 31-Mar-2022

5 views 0 download

transcript

Recursion: concepts,

examples, and makeChange

Acknowledgement: The following slides are

adopted, some with minor revisions, from

several lecture slides of the CS5 Green

course at Harvey Mudd.

Factorial: Iteration Code

n! = n(n-1)(n-2)…1

def factorial(n):

result = 1

for k in range(1, n+1):

result = result * k

return result

Recursion…

n! = n(n-1)(n-2)…1

n! = n (n-1)! “inductive definition”

Recursion…

n! = n(n-1)(n-2)…1

n! = n x (n-1)! “inductive definition”

0! = 1 “base case”

Why is

0! = 1?

Math Induction = CS Recursion

0! = 1

n! = n (n-1)!

Math

inductive

definition

Python (Functional)

recursive function

# recursive factorial

def factorial(n):

if n == 0:

return 1

else:

return n * factorial(n-1)

Is Recursion Magic?

# recursive factorial

def factorial(n):

if n == 0:

return 1

else:

return n*factorial(n-1)

factorial(3):

return 3 * factorial(2)

Is Recursion Magic?

# recursive factorial

def factorial(n):

if n == 0:

return 1

else:

return n*factorial(n-1)

factorial(3):

return 3 * factorial(2)

return 2 * factorial(1)

Is Recursion Magic?

# recursive factorial

def factorial(n):

if n == 0:

return 1

else:

return n*factorial(n-1)

factorial(3):

return 3 * factorial(2)

return 2 * factorial(1)

return 1 * factorial(0)

Is Recursion Magic?

# recursive factorial

def factorial(n):

if n == 0:

return 1

else:

return n*factorial(n-1)

factorial(3):

return 3 * factorial(2)

return 2 * factorial(1)

return 1 * factorial(0)

1

Is Recursion Magic?

# recursive factorial

def factorial(n):

if n == 0:

return 1

else:

return n*factorial(n-1)

factorial(3):

return 3 * factorial(2)

return 2 * factorial(1)

return 1 * factorial(0)

1

Is Recursion Magic?

# recursive factorial

def factorial(n):

if n == 0:

return 1

else:

return n*factorial(n-1)

factorial(3):

return 3 * factorial(2)

return 2 * factorial(1)

return 1 * factorial(0)

1

2

Is Recursion Magic?

# recursive factorial

def factorial(n):

if n == 0:

return 1

else:

return n*factorial(n-1)

factorial(3):

return 3 * factorial(2)

return 2 * factorial(1)

return 1 * factorial(0)

1

2

6

Computing the length of a list

>>> len([1, 42, “spam”])

3

>>> len([1, [2, [3, 4]]])

2

def len(L):

‘’’returns the length of list L’’’

Python has

this built-in!

Computing the length of a list

>>> len([1, 42, “spam”])

3

>>> len([1, [2, [3, 4]]])

2

def len(L):

‘’’returns the length of list L’’’

if L == []: return 0 # base case

Python has

this built-

in!

Computing the length of a list

>>> len([1, 42, “spam”])

3

>>> len([1, [2, [3, 4]]])

2

def len(L):

‘’’returns the length of list L’’’

if L == []: return 0 # base case

else: return 1 + len(L[1:])

Summing up the numbers in a list

>>> sum([3, 42, 7])

52

>>> sum([42])

42

>>> sum([])

0

def sum(L):

‘’’returns the sum of numbers in the list’’’

Python has

this built-in

too!

Worksheet

Summing up the numbers in a list

>>> sum([1, 42, 7])

50

>>> sum([42])

42

>>> sum([])

0

def sum(L):

‘’’returns the sum of numbers in the list’’’

if L == []: return 0

The base

case takes

care of the

simplest

case we

could get.

Summing up the numbers in a list

>>> sum([1, 42, 7])

50

>>> sum([42])

42

>>> sum([])

0

def sum(L):

‘’’returns the sum of numbers in the list’’’

if L == []: return 0

else: return ???

Summing up the numbers in a list

>>> sum([1, 42, 7])

50

>>> sum([42])

42

>>> sum([])

0

def sum(L):

‘’’returns the sum of numbers in the list’’’

if L == []: return 0

else: return L[0] + sum(L[1:])

Recursion = :^)“To understand recursion, you

must first understand recursion”

-anonymous Mudd alum

The following pages have

a number of exercises for

you to do (in your notes).

You’re welcome to work

at your own pace.

min

member

pal

Minimum!

>>> min([372, 112, 42, 451])

42

>>> min([16])

16

def min(L):

‘’’ returns smallest value in the list L ‘’’

[ ], ,

Assume that the list

always has at least one

number in it! Use len

as a helper function!

Minimum!

>>> min([372, 112, 42, 451])

42

>>> min([16])

16

def min(L):

‘’’ returns smallest value in the list L ‘’’

if ??? # base case?

[ ], ,

Assume that the list

always has at least one

number in it! Use len

as a helper function!

Minimum!

>>> min([372, 112, 42, 451])

42

>>> min([16])

16

def min(L):

‘’’ returns smallest value in the list L ‘’’

if len(L) == 1: return L[0] # base case!

return L[0]

else: return min(L[1:]

[ ], ,

Assume that the list

always has at least one

number in it! Use len

as a helper function!

Minimum!

>>> min([372, 112, 42, 451])

42

>>> min([16])

16

def min(L):

‘’’ returns smallest value in the list L ‘’’

if len(L) == 1: return L[0] # base case!

elif L[0] < min(L[1:]): ???return L[0]

else: return min(L[1:]

[ ], ,

Assume that the list

always has at least one

number in it! Use len

as a helper function!

Minimum!

>>> min([372, 112, 42, 451])

42

>>> min([16])

16

def min(L):

‘’’ returns smallest value in the list L ‘’’

if len(L) == 1: return L[0] # base case?

elif L[0] < min(L[1:]): return L[0]

else: return ???

[ ], ,

Assume that the list

always has at least one

number in it! Use len

as a helper function!

Minimum!

>>> min([372, 112, 42, 451])

42

>>> min([16])

16

def min(L):

‘’’ returns smallest value in the list L ‘’’

if len(L) == 1: return L[0] # base case?

elif L[0] < min(L[1:]): return L[0]

else: return min(L[1:])

[ ], ,

Assume that the list

always has at least one

number in it! Use len

as a helper function!

Member(Skipped in Class, Study on your own)

>>> member(42, [1, 3, 5, 42, 7])

True

>>> member(42, ['spam', 'is', 'yummy'])

False

def member(thing, myList):

‘’’ return True if thing in myList and

False otherwise. ‘’’

This is sort of like the “in”

thing in Python, but don’t

use “in” here. Just list

indexing, slicing, and

recursion!

member

>>> member(42, [1, 3, 5, 42, 7])

True

>>> member(42, ['spam', 'is', 'yummy'])

False

def member(thing, myList):

if myList == []: return ??? # base case

member

>>> member(42, [1, 3, 5, 42, 7])

True

>>> member(42, ['spam', 'is', 'yummy'])

False

def member(thing, myList):

if myList == []: return False # base case

elif thing == myList[0]: return True

member

>>> member(42, [1, 3, 5, 42, 7])

True

>>> member(42, ['spam', 'is', 'yummy'])

False

def member(thing, myList):

if myList == []: return False # base case

elif thing == myList[0]: return True

else: return member(thing, myList[1:])

Palindrome?(Skipped in Class, Study on your own)

>>> pal('radar')

True

>>> pal('amanaplanacanalpanama')

True

>>> pal('spam')

False

def pal(myString):

‘’’ returns True if myString is a

palindrome and False otherwise ‘’’

Palindrome?>>> pal('radar')

True

>>> pal('amanaplanacanalpanama')

True

>>> pal('spam')

False

def pal(myString):

‘’’ returns True if myString is a

palindrome and False otherwise ‘’’

if len(myString) <= 1: return True # base case

Palindrome?>>> pal('radar')

True

>>> pal('amanaplanacanalpanama')

True

>>> pal('spam')

False

def pal(myString):

‘’’ returns True if myString is a

palindrome and False otherwise ‘’’

if len(myString) <= 1: return True # base case

elif myString[0] != myString[-1]:

return False

else:

Palindrome?>>> pal('radar')

True

>>> pal('amanaplanacanalpanama')

True

>>> pal('spam')

False

def pal(myString):

‘’’ returns True if myString is a

palindrome and False otherwise ‘’’

if len(myString) <= 1: return True # base case

elif myString[0] != myString[-1]:

return False

else: return pal(myString[1:-1])

Change

>>> change(42, [25, 10, 5, 1])

5

>>> change(42, [10, 5, 1])

6 But in Shmorbodia…

In this problem, we’re allowed to use a coin denomination as many times as we want!

Change

>>> change(42, [25, 10, 5, 1])

5

>>> change(42, [10, 5, 1])

6

>>> change(42, [25, 21, 1])

In this problem, we’re allowed to use a coin denomination as many times as we want!

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

Let’s make change together!

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

if amount == 0: return ???

We’re making change!

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

if amount == 0: return 0

elif Coins == []: return ???

We’re making change!

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

if amount == 0: return 0

elif Coins == []: return float(‘inf’)

else:

It = Coins[0]

We’re making change!

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

if amount == 0: return 0

elif Coins == []: return float(‘inf’)else:

It = Coins[0]

if It > amount: return ???

else:

useIt =

loseIt =

return _____________________________________________

We’re making change!

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

if amount == 0: return 0

elif Coins == []: return float(‘inf’)else:

It = Coins[0]

if It > amount: return change(amount, Coins[1:])

else:

useIt =

loseIt =

return min(useIt, loseIt)

Python has a built in min function: min(42,5)is 5

Fill this in (in your notes)!

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

if amount == 0: return 0

elif Coins == []: return float(‘inf’)else:

It = Coins[0]

if It > amount: return change(amount, Coins[1:])

else:

useIt = 1 + change(amount-It, Coins)

loseIt =

return min(useIt, loseIt)

Fill this in (in your notes)!

Python has a built in min function: min(42,5)is 5

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

if amount == 0: return 0

elif Coins == []: return float(‘inf’)else:

It = Coins[0]

if It > amount: return change(amount, Coins[1:])

else:

useIt = 1 + change(amount-It, Coins)

loseIt = change(amount, Coins[1:])

return min(useIt, loseIt)

Fill this in (in your notes)!

Python has a built in min function: min(42,5)is 5

Change

>>> change(42, [25, 21, 1])

2

def change(amount, Coins):

if amount == 0: return 0

elif Coins == []: return float(‘inf’)else:

It = Coins[0]

if It > amount: return change(amount, Coins[1:])

else:

useIt = 1 + change(amount-It, Coins)

loseIt = change(amount, Coins[1:])

return min(useIt, loseIt)

Fill this in (in your notes)!

Python has a built in min function: min(42,5)is 5

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

cs124: a different exampledone on the black board.

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

2

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

2 inf

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

2 inf

2

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

2 inf

2

2

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

2 inf

2

2

3

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

2 inf

2

2

3

102

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

2 inf

2

2

3

102

2

change(10, [8, 5, 1])

useIt loseIt

1+change(2, [8, 5, 1]) change(10, [5, 1])

useIt loseIt

change(2, [5, 1])

useIt loseIt

1+change(5, [5, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

Forbidden!

Forbidden! change(2, [ 1])

useIt loseIt

1+change(1, [ 1]) change(2, [ ])

useIt loseIt

1+change(0, [ 1]) change(1, [ ])

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

1 inf

2 inf

2

2

3

102

2

change(10, [4, 2, 1])

useIt Lose It

1+change(6, [4, 2, 1]) change(10, [2, 1])

useIt loseIt

change(6, [2, 1])

useIt loseIt

1+change(8, [2, 1]) change(10, [1])

useIt loseIt useIt loseIt useIt loseIt

def change(amount, Coins):if amount == 0: return 0elif Coins == []: return float(‘inf’)else:

It = Coins[0]if It > amount:

return change(amount, Coins[1:])else:

useIt = 1 + change(amount-It, Coins)loseIt = change(amount, Coins[1:])return min(useIt, loseIt)

3

2

1+change(2, [4, 2, 1])

Forbidden! 1+ change(6, [2, 1])change(2, [2, 1])

useIt loseIt

1

This works, but it’s slow!

There is repeated work!!

Check your note and read the

textbook for memoizing change…

Another example

(done in class on

the board)

Show the coins, not just the number of coins

(Not covered in class, study on your own)

>>> change(42, [25, 21, 1])

2

def change( amount, denominations ):

''' Returns the least number of coins required to make the given

amount using the list of provided denominations.'''

if amount == 0: return 0

elif denominations == []: return float('infinity')

elif denominations[0] > amount: return change(amount, denominations[1:])

else:

useIt = 1 + change(amount - denominations[0], denominations)

loseIt = change(amount, denominations[1:])

return min(useIt, loseIt)

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

if amount == 0:

elif denominations == []:

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

if amount == 0: return [0, []]

elif denominations == []: return [float('infinity'), []]

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

if amount == 0: return [0, []]

elif denominations == []: return [float('infinity'), []]

elif denominations[0] > amount:

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

if amount == 0: return [0, []]

elif denominations == []: return [float('infinity'), []]

elif denominations[0] > amount: return showChange(amount, denominations[1:])

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

if amount == 0: return [0, []]

elif denominations == []: return [float('infinity'), []]

elif denominations[0] > amount: return showChange(amount, denominations[1:])

else:

useIt = showChange(amount - denominations[0], denominations)

loseIt = showChange(amount, denominations[1:])

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

if amount == 0: return [0, []]

elif denominations == []: return [float('infinity'), []]

elif denominations[0] > amount: return showChange(amount, denominations[1:])

else:

useIt = showChange(amount - denominations[0], denominations)

loseIt = showChange(amount, denominations[1:])

if useIt[0] <= loseIt[0]:

return useIt

else:

return loseIt

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

if amount == 0: return [0, []]

elif denominations == []: return [float('infinity'), []]

elif denominations[0] > amount: return showChange(amount, denominations[1:])

else:

useIt = showChange(amount - denominations[0], denominations)

useIt = [useIt[0] +1, [denominations[0]] + useIt[1] ]

loseIt = showChange(amount, denominations[1:])

if useIt[0] <= loseIt[0]:

return useIt

else:

return loseIt

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

change and showChange return different types

>>> change(42, [25, 21, 1])

2

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]

A common mistake...def change( amount, denominations ):

if amount == 0: return 0

elif denominations == []: return float('infinity')

elif denominations[0] > amount: return change(amount, denominations[1:])

else:

useIt = 1 + change(amount - denominations[0], denominations)

loseIt = change(amount, denominations[1:])

return min(useIt, loseIt)

def showChange( amount, denominations ):

if amount == 0: return [0, []]

elif denominations == []: return [float('infinity'), []]

elif denominations[0] > amount: return change(amount, denominations[1:])

else:

useIt = change(amount - denominations[0], denominations)

useIt = [useIt[0] +1, [denominations[0]] + useIt[1] ]

loseIt = change(amount, denominations[1:])

if useIt[0] <= loseIt[0]:

return useIt

else:

return loseIt

TypeErrorschmype error!

showChange

def showChange( amount, denominations ):

''' Takes an integer amount and a list of possible

denominations. Returns a list containing two elements. First

the minimum number of coins required, and second a list of the

actual coins used in that solution.'''

if amount == 0: return [0, []]

elif denominations == []: return [float('infinity'), []]

elif denominations[0] > amount: return showChange(amount, denominations[1:])

else:

useIt = showChange(amount - denominations[0], denominations)

useIt = [useIt[0] +1, [denominations[0]] + useIt[1] ]

loseIt = showChange(amount, denominations[1:])

if useIt[0] <= loseIt[0]:

return useIt

else:

return loseIt

>>> showChange(42, [25, 21, 1])

[2, [21, 21]]Demo