I solved kata on codewars. Acctually I did this by accident and I don't understand why this code works. May you explain it?
Kata:
Write a function, persistence, that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.
39 --> 3 (because 39 = 27, 27 = 14, 1*4 = 4 and 4 has only one digit)
My solution:
function persistence(num) {
let count = 0;
const arr = [...num.toString()];
const sumArr = arr.reduce((res, val) => (res *= val));
if (arr.length > 1) {
**// Why? How this line works?
// Why it doesn't crashes?
// Why it returns correct counter value and calls the function?**
count += 1 + persistence(sumArr)
}
return count;
}
persistence(39); //3
Why if I do like this, the counter do not save the result:
if (arr.length > 1) {
count += 1
persistence(sumArr) }
Basically, the persistence(sumArr) function acts as a recursive function and returns count of 0 for a base condition that is when the number is single digit.
For 39, count is 1+persistence(27)
For 27, count is 1+persistence(14)
and for 14, 1+ persistence (4) which is nothing but 1+0 and recursively it adds up to be 3
count is a local variable, only reachable within the scope of persistence(), so when you do a recursive loop, you create a new variable called count but it's in a new scope - the method that you called - it just happens to have the same name as persistence().
It would be totally different if count were a global variable, outside of the scope of the method.
let count = 0;
function persistence(num) {
...
}
Calling persistence() again within persistence() would then use the same variable, not a new one.
This is recursion!
Whenever a function is called by the caller, that function (a.k.a callee) is pushed into the call stack. All the arguments, local variables needed for that function is present there. This is also known as stack frame. The callee is popped out of the stack when it returns to the caller.
In your case both the caller and the callee happened to be the same function. This is called recursion. During recursion, variables local to that function aren't shared. A new stack frame is set up for each callee.
if (arr.length > 1) {
count += 1
persistence(sumArr)
}
Here, the count that you are returning from the callee isn't getting added up with the count of the caller.
If we visualize what is happening then:
persistence(37) = 1 + persistence(27) = 1 + 1 + 1 + 0 // [putting value returned from persistence(27)]
persistence(27) = 1 + persistence(14) = 1 + 1 + 0 // [putting value returned from persistence(14)]
persistence(14) = 1 + persistence(4) = 1 + 0 // [putting value returned from persistence(4)]
persistence(4) = 0