Search code examples
rubysicp

sicp counting change exericse


I am working on the counting change algorithm found in the SICP book. I am trying to get it right in Ruby. First, I had trouble with syntax failing now, it has turned into an infinite loop

irb(main):001:0> count_change(5)

SystemStackError: stack level too deep from .../.rbenv/versions/2.1.1/lib/ruby/2.1.0/irb/workspace.rb:86 Maybe IRB bug!

I thought it would be a good time to use StackOverflow. It will help out a lot if you can help. I think the problem is on line 12. Thanks.

def count_change amount
  cc(amount, 5)
end

def cc(amount, kinds_of_coins)
  if amount == 0
    1
  elsif amount < 0 || kinds_of_coins == 0
    0
  else
    cc amount, (kinds_of_coins - 1) + 
        cc((amount - (first_denomination(kinds_of_coins))), kinds_of_coins)
  end
end

def first_denomination(kinds_of_coins)
  if kinds_of_coins == 1
    1
  elsif kinds_of_coins == 2
    5
  elsif kinds_of_coins == 3
    10
  elsif kinds_of_coins == 4
    25
  elsif kinds_of_coins == 5
    50
  end
end

Solution

  • Your problem is in this line:

    cc amount, (kinds_of_coins - 1) + 
        cc((amount - (first_denomination(kinds_of_coins))), kinds_of_coins)
    

    Which is actually

    cc(amount, 
     (kinds_of_coins - 1) + cc((amount - (first_denomination(kinds_of_coins))), kinds_of_coins))
    

    when amount is 5 and kinds_of_coins is 2 (amount - (first_denomination(kinds_of_coins))) returns 0, which means that cc(0, anything) returns 1 - and the next recursion is cc(5, 2) again...

    I'm not familiar with the SICP algorithm but I suspect what you meant to write was

    cc(amount, (kinds_of_coins - 1)) + 
        cc((amount - (first_denomination(kinds_of_coins))), kinds_of_coins)