There are four types of common coins in   US   currency:

   quarters   (25 cents)
   dimes   (10 cents)
   nickels   (5 cents),   and 
   pennies   (1 cent) 


There are six ways to make change for 15 cents:

   A dime and a nickel 
   A dime and 5 pennies
   3 nickels
   2 nickels and 5 pennies
   A nickel and 10 pennies
   15 pennies


Task

How many ways are there to make change for a dollar using these common coins?     (1 dollar = 100 cents).



Optional

Less common are dollar coins (100 cents);   and very rare are half dollars (50 cents).   With the addition of these two coins, how many ways are there to make change for $1000?

(Note:   the answer is larger than   232).



References

 an algorithm from the book Structure and Interpretation of Computer Programs.
 an article in the algorithmist.
 Change-making problem on Wikipedia.


defmodule Coins do
  def find(coins,lim) do
    vals = Map.new(0..lim,&{&1,0}) |> Map.put(0,1)
    count(coins,lim,vals)
      |> Map.values
      |> Enum.max
      |> IO.inspect
  end
 
  defp count([],_,vals), do: vals
  defp count([coin|coins],lim,vals) do
    count(coins,lim,ways(coin,coin,lim,vals))
  end
 
  defp ways(num,_coin,lim,vals) when num > lim, do: vals
  defp ways(num, coin,lim,vals) do
    ways(num+1,coin,lim,ad(coin,num,vals))
  end
 
  defp ad(a,b,c), do: Map.put(c,b,c[b]+c[b-a])
end
 
Coins.find([1,5,10,25],100)
Coins.find([1,5,10,25,50,100],100_000)