Recently, I wrote a simple program to solve the change-making problem. Rather than the tabular dynamic programming solution (described in the link), I tried to write a solution that uses memoization.
usd = [25, 10, 5, 1]
def make_change(W, denoms=usd):
"""
Solves the change-making problem where W is
a given amount of money and denoms
is a list of the denominations available
>>> make_change(6,[3,1])
(3, 3)
"""
d = {}
def inner(W, sol):
if W == 0:
return sol
if W in d:
return d[W]
tmp = []
for coin in denoms:
w = W - coin
if w >= 0:
tmp.append(inner(w, sol + (coin,)))
d[W] = min(tmp, key=lambda x : len(x))
return d[W]
return inner(W, tuple())
if __name__ == "__main__":
import doctest
doctest.testmod()
I'm wondering if there's a better way I should be doing the memoization (i.e. a decorator):
def memoize(f):
d = {}
def inner(args):
if args not in d:
d[args] = f(*args)
return d[args]
return inner
The above code caches the arguments so they don't get recomputed in future computations. Here, however, I think we only want to cache the solution for a given W
, and I'm not sure a general purpose decorator like the one above is necessarily correct.