Hi,

Here is my solution. It's ruby19 only.

The test cases posted in the quiz thread should be solved in no time
(<
1sec). The only case I have found yet that takes some time to solve
is
something like:

    make_change(998, [3, 6, 9, 12])
    # => nil

We sort the coins in descending order and use this knowledge to cut
of
certain searches.

Regards,
Thomas.



#!/usr/bin/env ruby19
# Author::      Thomas Link (micathom AT gmail com)
# Created::     2008-01-25.

def make_change(amount, coins = [25, 10, 5, 1])
    # I use the ruby19 syntax here in order to make sure this code
isn't
    # run with ruby18 (because of the return statements).
    changer = ->(amount, coins, max_size) do
        return [] if amount == 0
        return nil if coins.empty? or
            max_size <= 0 or
            (amount.odd? and coins.all? {|c| c.even?})
        set = nil
        max_size1 = max_size - 1
        coins.each_with_index do |coin, i|
            n_coins = amount / coin
            # The coin value is getting too small
            break if n_coins > max_size
            if amount >= coin
                if amount % coin == 0
                    # Since coins are sorted in descending order,
                    # this is the optimal solution.
                    set = [coin] * n_coins
                    break
                else
                    other = changer.call(amount - coin,
                                         coins[i, coins.size],
                                         max_size1)
                    if other
                        set = other.unshift(coin)
                        max_size  = set.size - 1
                        max_size1 = max_size - 1
                    end
                end
            end
        end
        return set
    end

    coins  = coins.sort_by {|a| -a}
    # We don't care about micro-pennies.
    amount = amount.to_i
    changer.call(amount, coins, amount / coins.last)
end


if __FILE__ == $0
    args  = ARGV.map {|e| e.to_i}
    coins = make_change(args.shift, (args.empty? ? [25, 10, 5, 1] :
args).sort_by {|a| -a})
    if coins
        puts "#{coins.inject(0) {|a, c| a += c}}/#{coins.size}:
#{coins.join(' ')}"
    else
        puts "Please go away."
    end
end