My solution:
#Define the coins with value
#(Remark: Ruby Hashs are ordered, so this can be used).
VALUES = {
#'$' => 100,
:H => 50,
:Q => 25,
:D => 10,
:N => 5,
:P => 1,
}
# In: Get money in cents
# Out: Change the minimum quantity of coins
def make_change2make_change(amount, values = VALUES)
change = {}
values.each{|coin, value|
num, amount = amount.divmod(value)
change[coin] = num if num > 0
}
change
end
Test:
[23,100,42,91].each{|i|
puts "%-4i: %-10s" % [ i, make_change2make_change(i)]
}
result:
23 : {:D=>2, :P=>3}
100 : {:H=>2}
42 : {:Q=>1, :D=>1, :N=>1, :P=>2}
91 : {:H=>1, :Q=>1, :D=>1, :N=>1, :P=>1}
One advantage of my solution: You can add new coins very easy. Just add '$' => 100, to support a one dollar coin. (The name of the coin must be uniq!).
Or just give your own coin definition as parameter, e.g. for Euros:
EUR_VALUES = {
:'2EUR' => 200,
:EUR => 100,
50 => 50,
20 => 20,
10 => 10,
5 => 5,
2 => 2,
1 => 1,
}
[23,42,91,100,101].each{|i|
puts "%-4iEUR-Cents: %-10s" % [ i, make_change(i, EUR_VALUES)]
}
Result:
23 EUR-Cents: {20=>1, 2=>1, 1=>1}
42 EUR-Cents: {20=>2, 2=>1}
91 EUR-Cents: {50=>1, 20=>2, 1=>1}
100 EUR-Cents: {:EUR=>1}
101 EUR-Cents: {:EUR=>1, 1=>1}