Problem 4: Count change (200pts)
Denomination is a proper description of a currency amount, usually for coins or banknotes. For example, we have 1 Yuan coins and 100 Yuan bills in Chinese Yuan.
A currency system can be described by a special function that takes in an argument ith
and returns the ith smallest denomination in that currency system.
For example, the following money function describes Chinese Yuan (1 Yuan, 5 Yuan, 10 Yuan, 20 Yuan, 50 Yuan and 100 Yuan).
chinese_yuan(2)
returns 5
as 5 Yuan is the second smallest denomination.
When ith
does not correspond to any denomination, money function returns None
.
For example, chinese_yuan(7)
yields None
since there are only 6 distinct denominations in Chinese Yuan.
def chinese_yuan(ith):
if ith == 1:
return 1
if ith == 2:
return 5
if ith == 3:
return 10
if ith == 4:
return 20
if ith == 5:
return 50
if ith == 6:
return 100
Given an amount of money total
and a currency system, a set of banknotes (coins) makes change for total
if sum of their values is exactly total
. For example, the following sets make change for 15 Chinese Yuan:
- 15*1-Yuan
- 10*1-Yuan + 1*5-Yuan
- 5*1-Yuan + 2*5-Yuan
- 5*1-Yuan + 1*10-Yuan
- 3*5-Yuan
- 1*5-Yuan + 1*10-Yuan
Thus, there are 6 different ways to make change for 15 Chinese Yuan.
Write a recursive function count_change
that takes a positive integer total
and a money function money
and returns the number of ways to make change for total
under the currency system described by money
.
Hint: Refer to the implementation of
count_partitions
for an example of how to count the ways to sum up to a total with smaller parts. If you need to keep track of more than one value across recursive calls, consider writing a helper function and pass around the intermediate values as the arguments of the helper function.
def count_change(total, money):
"""Return the number of ways to make change for total,
under the currency system described by money.
>>> def chinese_yuan(ith):
... if ith == 1:
... return 1
... if ith == 2:
... return 5
... if ith == 3:
... return 10
... if ith == 4:
... return 20
... if ith == 5:
... return 50
... if ith == 6:
... return 100
>>> def us_cent(ith):
... if ith == 1:
... return 1
... if ith == 2:
... return 5
... if ith == 3:
... return 10
... if ith == 4:
... return 25
>>> count_change(15, chinese_yuan)
6
>>> count_change(49, chinese_yuan)
44
>>> count_change(49, us_cent)
39
>>> count_change(49, lambda x: 2 ** (x - 1))
692
>>> from construct_check import check
>>> # ban iteration
>>> check(HW_SOURCE_FILE, 'count_change', ['While', 'For'])
True
"""
"*** YOUR CODE HERE ***"