お題:ある金額になるコインの組み合わせ

お題:ある金額になるコインの組み合わせ - No Programming, No Life

rubyで回答
# coding: CP932
require "rspec"

def total_coins_pattern(total, *coins)
  total = total.to_i
  coins = [*coins].flatten
  min_coin = coins.min.to_i
  size = min_coin.zero? || total.zero? ? exit(false) : total / min_coin
  1.upto(size).inject([]){|r, n| r + coins.repeated_combination(n).select{|c| c.inject(:+).eql?(total)} }.compact.sort
end

def total_coins_output(total, coins, &block)
  result = yield(total, coins)
<<EOS

コインの種類:#{coins.join(", ")}
金額:#{total}
組み合わせ数:#{result.count}
組み合わせ:
#{result.map(&:to_s).join("\n").delete('"')}
EOS
end

describe "total_coins_pattern" do

  context "with argument 1, [1]" do
    subject { total_coins_pattern(1, [1]) }
    it { should eq [[1]] }
  end

  context "coins [1, 5, 10, 50, 100, 500]" do

    let(:coins){[1, 5, 10, 50, 100, 500]}

    context "total 1" do
      subject { total_coins_pattern(1, coins) }
      it { should eq [[1]] }
    end

    context "total 4" do
      subject { total_coins_pattern(4, coins) }
      it { should eq [[1, 1, 1, 1]] }
    end

    context "total 5" do
      subject { total_coins_pattern(5, coins) }
      it { should eq [[1, 1, 1, 1, 1], [5]] }
    end

    context "total 6" do
      subject { total_coins_pattern(6, coins) }
      it { should eq [[1, 1, 1, 1, 1, 1], [1, 5]] }
    end

    context "total 10" do
      subject { total_coins_pattern(10, coins) }
      it { should eq [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 5], [5, 5], [10]] }
    end

    context "total 11" do
      subject { total_coins_pattern(11, coins) }
      it { should eq [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 5], [1, 5, 5], [1, 10]] }
    end

  end

end

describe "total_coins_output" do

  context "with argument 10, [1, 5, 10, 50, 100, 500], &block" do

    subject { total_coins_output(10, [1, 5, 10, 50, 100, 500]){|total, coins| total_coins_pattern(total, coins)} }
    it { should eq <<EOS }

コインの種類:1, 5, 10, 50, 100, 500
金額:10
組み合わせ数:4
組み合わせ:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 5]
[5, 5]
[10]
EOS
  end

end

__END__
total_coins_pattern
  with argument 1, [1]
    should == [[1]]
  coins [1, 5, 10, 50, 100, 500]
    total 1
      should == [[1]]
    total 4
      should == [[1, 1, 1, 1]]
    total 5
      should == [[1, 1, 1, 1, 1], [5]]
    total 6
      should == [[1, 1, 1, 1, 1, 1], [1, 5]]
    total 10
      should == [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 5], [5, 5], [10]]
    total 11
      should == [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 5], [1, 5, 5], [1, 10]]

total_coins_output
  with argument 10, [1, 5, 10, 50, 100, 500], &block
    should ==
コインの種類:1, 5, 10, 50, 100, 500
金額:10
組み合わせ数:4
組み合わせ:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 5]
[5, 5]
[10]