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 money function is a function which takes a positive integer representing a denomination and returns the next larger denomination of the input or None
if there is no larger denomination. Its behavior is undefined if the input is not a valid denomination.
Money function can be used to describe a currency system. For example, the following money function describes Chinese Yuan (1 Yuan, 5 Yuan, 10 Yuan, 20 Yuan, 50 Yuan and 100 Yuan). You can assume the smallest denomination of all currencies is always 1.
def chinese_yuan(money):
if money == 1:
return 5
if money == 5:
return 10
if money == 10:
return 20
if money == 20:
return 50
if money == 50:
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 next_money
and returns the number of ways to make change for total
under the currency system described by next_money
.
Hint: Refer 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.
def count_change(total, next_money):
"""Return the number of ways to make change for total,
under the currency system described by next_money.
>>> def chinese_yuan(money):
... if money == 1:
... return 5
... if money == 5:
... return 10
... if money == 10:
... return 20
... if money == 20:
... return 50
... if money == 50:
... return 100
>>> def us_cent(money):
... if money == 1:
... return 5
... elif money == 5:
... return 10
... elif money == 10:
... 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: x * 2)
692
>>> from construct_check import check
>>> # ban iteration
>>> check(HW_SOURCE_FILE, 'count_change', ['While', 'For'])
True
"""
"*** YOUR CODE HERE ***"