Home > OS >  Recursive approach to Persistent bugger problem returns undefined
Recursive approach to Persistent bugger problem returns undefined

Time:04-27

I've been trying to solve the following problem in codewars using recursion:

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. For example (Input --> Output):

39 --> 3 (because 3*9 = 27, 2*7 = 14, 1*4 = 4 and 4 has only one digit)
999 --> 4 (because 9*9*9 = 729, 7*2*9 = 126, 1*2*6 = 12, and finally 1*2 = 2)
4 --> 0 (because 4 is already a one-digit number)

Here's what I've tried:

var numOfIterations = 0;
function persistence(num) {
   //code me
  var i;
  var digits=[];
  var result = 1;
  if (num.toString().length==1) {
    return numOfIterations;
  } else {
      numOfIterations  ;
      digits = Array.from(String(num), Number);
      for (i=0;i<digits.size;i  ) {
        result=result*digits[i];
      }
      persistence(result);
    }
}

But for some reason, instead of returning the number of iterations, it returns undefined. I've been told that I'm not using recursion correctly, but I just can't find the problem.

CodePudding user response:

I've been told that I'm not using recursion correctly

You're recursing, but you're not returning the result of that recursion. Imagine for a moment just this structure:

function someFunc() {
  if (someCondition) {
    return 1;
  } else {
    anotherFunc();
  }
}

If someCondition is false, what does someFunc() return? Nothing. So it's result is undefined.

Regardless of any recursion, at its simplest if you want to return a result from a function then you need to return it:

function persistence(num) {
  //...
  if (num.toString().length==1) {
    //...
  } else {
    //...
    return persistence(result); // <--- here
  }
}

CodePudding user response:

As @David wrote in his answer, you were missing the return of the recursive call to itself. Plus you were using digits.size instead of digits.length

var numOfIterations = 0;
function persistence(num) {
   //code me
  var i;
  var digits=[];
  var result = 1;
  if (num.toString().length==1) {
    return numOfIterations;
  } else {
      numOfIterations  ;
      digits = Array.from(String(num), Number);
      for (i=0;i<digits.length;i  ) {
        result= result * digits[i];
      }
      return persistence(result);
    }
}

numOfIterations = 0;
var o = persistence(1223)

CodePudding user response:

You can do something like this

const persistenceTailRecursive = (num, iterations = 0) => {
  const str = ''   num;
  if(str.length === 1){
    return iterations;
  }
  return persistenceTailRecursive(str.split('').reduce((res, a) => res * parseInt(a), 1), iterations   1)
}

const persistence = (num) => {
  const str = ''   num;
  if(str.length === 1){
    return 0;
  }
  return  1   persistence(str.split('').reduce((res, a) => res * parseInt(a), 1))
}

console.log(persistenceTailRecursive(93))
console.log(persistenceTailRecursive(999))

console.log(persistence(93))
console.log(persistence(999))

There are 2 versions

1 tailRecursive call the same method with the exact signature (preventing stackoverflow in some languages like scala)

2 basic the result is calculated at the end

  • Related