I'm working on an algorithm to count the number of ways to build 100 cents given an infinite amount of pennies, dimes, nickels, and quarters.
I ended up coming with the above (which AFAIK works):
def count_ways(amount)
num_ways(amount, 0)
end
def num_ways(amount, index)
return 1 if amount == 0
return 0 if index >= COINS.length || amount < 0
num_ways(amount - COINS[index], index) +
num_ways(amount, index + 1)
end
Now, I'd like to memoize this algorithm. An effective way I've found to think about memoizing is to consider what inputs do we pass into this function repeatedly. In this case, I'd like to memoize the combination of amount & index parameters.
Typically when I have two parameters, I build a two D array as a way to memoize but here that makes a lot less sense. Consequently, how can you memoize off of these two parameters? Does it make sense to do something like this?
def count_ways(amount)
memo = Hash.new { |h, k| h[k] = [] }
num_ways(amount, 0, memo)
end
def num_ways(amount, index, memo)
return 1 if amount == 0
return 0 if index >= COINS.length || amount < 0
memo[amount - COINS[index], index] ||= num_ways(amount - COINS[index], index)
memo[amount, index + 1] ||= num_ways(amount, index + 1)
memo[amount - COINS[index], index] +
memo[amount, index + 1]
end