0

I went step by step looking at this function and it seems to me that it should avoid calling sortedCoins(0-1) by using only sortedCoins(0) and terminating when y == -1, but somehow it doesn't. Why?

def countChange(amount: Int, coins: List[Int]): Int = { 
    var x = coins.length 
    var y = x
    val sortedCoins = coins.sortWith(_ < _) 
    def cc(amount: Int, x: Int): Int = {
        y -= 1
        if (amount == 0) 1 
        else if (y == 0) cc(amount - x, sortedCoins(y))
        else if (amount < 0 || y == -1) 0  
        else cc(amount, sortedCoins(y - 1)) + cc(amount - x, sortedCoins(y))    
    }

    cc(amount, x) 
}
The Archetypal Paul
  • 41,321
  • 20
  • 104
  • 134
Dominik
  • 121
  • 1
  • 2
  • 10
  • 1
    I suggest learning how to use a debugger to step line by line through the execution of a program. It would be really useful to you (for this and future problems). It's surprising how many questions are asked that the asker could have more easily solved for themselves in this way – The Archetypal Paul Feb 02 '17 at 14:53
  • on another note it kills me when i see `coins: List[Int]` where it should probably be `coins: List[Coin]`. At a minimum you should use a value class, but here in fact you should use an ADT (Algebraic Data Type) – raphaëλ Feb 02 '17 at 16:00
  • Is this a homework problem? Seems like I've seen this in a Coursera course.... – WillD Feb 02 '17 at 18:44
  • Yes, there is a problem to solve with such definition signature of countChange function. Fighting with this puzzle for 10 hours already – Dominik Feb 02 '17 at 23:32

1 Answers1

3

You need to rethink way in which you are writing this algorithm. You see your y variable is "global" scope in your recursive function, when you execute your function it will go to

cc(amount, sortedCoins(y - 1)) + cc(amount - x, sortedCoins(y))

multiple times, and it will execute first side of equation and it will decrement y every time. Then, y will become 0 and your

else if (y == 0)  cc(amount - x, sortedCoins(y))

line will be executed, next because y=-1 your

else if (amount < 0 || y < 0) 0 

line will be executed. And here we come to exception, because this line returned 0, recursively second part of equation of last else will be executed, which is

cc(amount - x, sortedCoins(y))

, and right now y=-1, that is why you have this exception. I hope this is understandable.

Kamil Banaszczyk
  • 1,133
  • 1
  • 6
  • 23
  • `else if (amount < 0 || y == -1) 0 ` If this returns 0 then the function should terminate because the function returns Int. Why does it continue and checks the next "else"? – Dominik Feb 02 '17 at 14:53
  • It doesn't check the next else, you recursively invoke to times cc function. When left side of equation return 0, the right side of equation is invoked, with parameters like (amount - x, sortedCoins(y)) and why there is -1. sortedCoins is List so you have indexOutOfBound – Kamil Banaszczyk Feb 02 '17 at 15:04