why doesn't this backtracking recursion go to other branches?
-
26-12-2019 - |
Question
Given an array, and a goal (number), I have to determine if it is possible to reach goal by adding elements from the array. Here is my code (in javascript), and some results:
function check(goal,array) {
function add(sum, array) {
if (sum == goal)
return true;
else if ((sum > goal)||(!array[0]))
return false;
else
console.log(sum); // check where we are
return add(sum + array.shift(),array) || add(sum,array);
}
return add(0,array);
}
What I expect to happen to the stack of add() after calling check(6,[1,3,5])
add(0,[1,3,5]) // log 0
add(1,[3,5]) //log 1
add(1+3,[5]) //log 4
add(1+3+5,[]) //return false
add(1+3,[]) //return false
add(1,[5]) //log 1
add(1+5,[]) //return true
add(1,[])
add[0,[3,5])
add(0+3,[5])
add(0+3+5,[])
add(0+3,[])
add(0,[5])
add(0+5,[])
add(0,[])
Actual results:
check(6,[1,3,5])
false
0
1
4
check(3,[1,3,5])
false
0
1
1
It never leaves the first branch! Why ? Edit: Ok, based on the suggestions, I guess it's better to avoid passing array as an argument:
function check(goal,array) {
function add(sum, i) {
if (sum == goal)
return true;
else if ((sum > goal)||(i==array.length))
return false;
else
console.log(sum);
return add(sum + array[i],i+1) || add(sum,i+1);
}
return add(0,0);
}
It works fine here.
Solution
It's the same array that's passed around, and after the first branch it'll become empty so the recursion will finish. Try it with a copy:
function check(goal,array) {
function add(sum, array) {
if (sum == goal)
return true;
else if ((sum > goal)||(!array[0]))
return false;
else
print(sum);
array = array.slice();
return add(sum + array.shift(),array) || add(sum,array);
}
return add(0,array);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow