Making Change (#154)

The three rules of Ruby Q.:

  1. Please do not post any solutions or spoiler discussion for this quiz
    until
    48 hours have passed from the time on this message.

  2. Support Ruby Q. by submitting ideas as often as you can:

http://www.rubyquiz.com/

  1. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem helps
everyone
on Ruby T. follow the discussion. Please reply to the original quiz
message,
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

In “Practical Ruby Projects,” the author includes a couple of chapters
involving
coin simulations. These simulators are used to explore the
possibilities of
replacing a certain coin or adding a new coin.

One interesting subproblem of these simulations is that of making
change. For
example, if we need to give 39 cents change in the United States (where
there
are 25, 10, 5, and 1 cent pieces), we can give:

make_change(39)
=> [25, 10, 1, 1, 1, 1]

What if the coins were 10, 7, and 1 cent pieces though and we wanted to
make 14
cents change? We would probably want to do:

make_change(14, [10, 7, 1])
=> [7, 7]

This week’s Ruby Q. is to complete a change making function with this
skeleton:

def make_change(amount, coins = [25, 10, 5, 1])

end

Your function should always return the optimal change with optimal being
the
least amount of coins involved. You can assume you have an infinite
number of
coins to work with.

James,

What if the coins were 10, 7, and 1 cent pieces though
and we wanted to make 14 cents change? We would
probably want to do:

make_change(14, [10, 7, 1])
=> [7, 7]

Your function should always return the optimal change
with optimal being the least amount of coins involved.

Do you have a preference for breaking ties?  For example, which

would you prefer for make_change(21, [10, 7, 1]): [7, 7, 7] or [10, 10,
1]?

Warren B.

On Jan 25, 2008, at 10:55 AM, Warren B. wrote:

with optimal being the least amount of coins involved.

Do you have a preference for breaking ties? For example, which
would you prefer for make_change(21, [10, 7, 1]): [7, 7, 7] or [10,
10,
1]?

No preference. Either is a valid answer.

James Edward G. II

Are the coin values always given in descending order?

regards,
thomas.

On Jan 25, 2008, at 1:49 PM, tho_mica_l wrote:

Are the coin values always given in descending order?

Is it that hard to call sort()? :slight_smile:

I don’t mind if you want to assume they are.

James Edward G. II

James G. wrote:

On Jan 25, 2008, at 10:55 AM, Warren B. wrote:

with optimal being the least amount of coins involved.

Do you have a preference for breaking ties? For example, which
would you prefer for make_change(21, [10, 7, 1]): [7, 7, 7] or [10,
10,
1]?

No preference. Either is a valid answer.

James Edward G. II

I don’t know…I hate pennies. IMHO, any answer that minimizes the
number of pennies should win out.

On Jan 25, 2008 9:53 PM, Dominik H. [email protected] wrote:

On [Sat, 26.01.2008 00:50], Ruby Q. wrote:

In “Practical Ruby Projects,” the author includes a couple of chapters involving
coin simulations. These simulators are used to explore the possibilities of
replacing a certain coin or adding a new coin.

Are there any advanced combinations of change/array of coins which are likely to fail
on some implementations?

Is it ok to share test cases before the spoiler? I assume it is, and
it this case everybody could send a couple…

Jesus.

On [Sat, 26.01.2008 00:50], Ruby Q. wrote:

In “Practical Ruby Projects,” the author includes a couple of chapters involving
coin simulations. These simulators are used to explore the possibilities of
replacing a certain coin or adding a new coin.

Are there any advanced combinations of change/array of coins which are
likely to fail
on some implementations?

On Jan 25, 2008, at 3:09 PM, Jesús Gabriel y Galán wrote:

on some implementations?

Is it ok to share test cases before the spoiler?

Sure.

James Edward G. II

On Jan 25, 2008 10:24 PM, James G. [email protected] wrote:

On Jan 25, 2008, at 3:09 PM, Jesús Gabriel y Galán wrote:

Is it ok to share test cases before the spoiler?

Sure.

This is what I’m currently working on:

require ‘test/unit’

class TestMakeChange < Test::Unit::TestCase
def test_zero
assert_equal([], make_change(0))
end

def test_change_equal_to_one_coin
assert_equal([10], make_change(10, [10, 7, 1]))
assert_equal([7], make_change(7, [10, 7, 1]))
end

def test_two_middles
assert_equal([7, 7], make_change(14, [10, 7, 1]))
end
end

For now:

3 tests, 3 assertions, 3 failures, 0 errors

:frowning:

It’s not really surprising, since I still have an empty method :slight_smile:

Jesus.

On Jan 25, 2008 9:20 PM, James G. [email protected] wrote:

On Jan 25, 2008, at 1:49 PM, tho_mica_l wrote:

Are the coin values always given in descending order?

Is it that hard to call sort()? :slight_smile:
funny mistake of yours James :slight_smile:
Robert

On Jan 25, 2008, at 4:30 PM, Robert D. wrote:

On Jan 25, 2008 9:20 PM, James G. [email protected] wrote:

On Jan 25, 2008, at 1:49 PM, tho_mica_l wrote:

Are the coin values always given in descending order?

Is it that hard to call sort()? :slight_smile:
funny mistake of yours James :slight_smile:

I guess I should have said: is it that hard to call sort { |a,b| b
<=> a }?

James Edward G. II

For anyone interested, here are the Australian coin values:
[200, 100, 50, 20, 10, 5] # $2 and $1 are coins. We also have no 1c
or 2c

This means I have to consider the case where it is not possible to
construct the amount from the given coins, eg. $7.99

Nice to have one I could do in the ten minutes after breakfast while
the kids get dressed :slight_smile:

Cheers,
Dave

On 25 Jan 2008, at 20:53, Dominik H. wrote:

Are there any advanced combinations of change/array of coins which
are likely to fail
on some implementations?

result may not be achievable using just lowest value coin

make_change(11,[10,9,2]) #=> [9,2]

/dh

Are there any advanced combinations of change/array of coins which
are likely to fail
on some implementations?

make_change 14, [10,7,3]

my original implementation missed this one

James G. [2008-01-25 23:57]:

I guess I should have said: is it that hard to call sort { |a,b|
b <=> a }?
am i missing something? what’s wrong with sort.reverse? apart from
the fact that it’s a whole lot faster :wink:

i know, this is not all too serious, but just for the fun of it…
here are the timings for M = 10, 100, 1_000, 10_000:

         user     system      total        real

block 3.940000 0.410000 4.350000 ( 4.349146)
by 2.580000 0.290000 2.870000 ( 3.033811)
reverse 0.260000 0.020000 0.280000 ( 0.287276)

block 8.540000 0.870000 9.410000 ( 9.406218)
by 2.740000 0.210000 2.950000 ( 2.953615)
reverse 0.180000 0.000000 0.180000 ( 0.179436)

block 13.810000 1.340000 15.150000 ( 15.176457)
by 2.880000 0.220000 3.100000 ( 3.099212)
reverse 0.220000 0.010000 0.230000 ( 0.234392)

block 17.820000 2.230000 20.050000 ( 20.255648)
by 3.380000 0.280000 3.660000 ( 3.656010)
reverse 0.300000 0.010000 0.310000 ( 0.305090)

----[ sort_bench.rb ]----
require ‘benchmark’

M = ARGV.first.to_i
N = 1_000_000 / M
A = (0…M).sort_by { rand }

Benchmark.bm(7) { |x|
x.report(‘block’) { N.times { A.sort { |a, b| b <=> a } } }
x.report(‘by’) { N.times { A.sort_by { |a| a * -1 } } }
x.report(‘reverse’) { N.times { A.sort.reverse } }
}

cheers
jens

Same here in South Africa. We’re phasing out 1c & 2c coins so change of
R7.99 would usually be R8.00 (ie. The store rounds to the benefit of the
consumer)
This could be applied to a case like make_change(14, [10,5,3]) where the
answer is [10,5] as the answer should leave the change giver the least
out
of pocket?

Andrew T.
[email protected]
082 415 8283
skype: andrewtimberlake

“I have never let my schooling interfere with my education.”
–Mark Twain

Why would this fail? The answer would be [7,7]
make_change 14, [10, 5, 3] would fail though (see my previous post on a
possible addendum to the quiz to handle cases like this though - instead
of
failing)

Andrew T.
[email protected]
082 415 8283
skype: andrewtimberlake

“I have never let my schooling interfere with my education.”
–Mark Twain

2008/1/26, Andrew T. [email protected]:

make_change 14, [10, 5, 3] would fail though (…)

=> [5, 3, 3, 3]

Regards,
Pit

On Jan 25, 2008, at 5:44 PM, Jens W. wrote:

James G. [2008-01-25 23:57]:

I guess I should have said: is it that hard to call sort { |a,b|
b <=> a }?
am i missing something? what’s wrong with sort.reverse? apart from
the fact that it’s a whole lot faster :wink:

Because my first computer science teacher drilled into my head that
you sort it correctly in the first place, instead of using two
operations to get what you wanted. I guess he hadn’t run into Ruby
yet. :wink:

James Edward G. II