2

I just started out with recursion so I was solving a question which is like

Create a function that takes numbers as arguments, adds them together, and returns the product of digits until the answer is only 1 digit long.

sumDigProd(16, 28) ➞ 6
// 16 + 28 = 44
// 4 * 4 =  16
// 1 * 6 = 6

sumDigProd(0) ➞ 0

sumDigProd(1, 2, 3, 4, 5, 6) ➞ 2

so i did it with recursion as

function sumDigProd(...digits) {
  let ans = digits.reduce((a, b) => a + b, 0);
  console.log(ans);
  const result=calc(ans);
 function calc(ans) {
    ans = ans.toString();
    let pro = 1;
    for (let i = 0; i < ans.length; i++) {
      pro = pro * ans[i];
    }
    console.log(pro);
    while (pro > 10) {
      calc(pro);
    }
    return pro
   
  }
  return result
}
console.log(sumDigProd(16,28));

so I am running it in infinite loop

13
  • This doesn't require recursion. Commented May 10, 2020 at 19:38
  • What is sevenBoom()? Commented May 10, 2020 at 19:40
  • but how i can only think of recursion as a solution to this Commented May 10, 2020 at 19:40
  • @kmoser sorry type error Commented May 10, 2020 at 19:40
  • You don't assign the return value from the recursive call. It should be assigned to pro. Commented May 10, 2020 at 19:41

5 Answers 5

5

You did not assign the return value from the recursive call.

Also, you are mixing an iterative solution (with while) with a recursive one. You need one of the two, not both.

For the recursive solution you can just use an if. And in that case you can even immediately return the return value from the recursive call.

Also, the condition should be pro >= 10, as 10 is not OK as a final value:

function sumDigProd(...digits) {
  let ans = digits.reduce((a, b) => a + b, 0);
  console.log(ans);

  function calc(ans) {
    ans = ans.toString();
    let pro = 1;
    for (let i = 0; i < ans.length; i++) {
      pro = pro * ans[i];
    }
    console.log(pro);
    if (pro >= 10) {
      return calc(pro); // recursive case
    }
    return pro; // base case
  }

  return calc(ans);
}
console.log(sumDigProd(16,28));

An iterative solution could be achieved with little change:

function sumDigProd(...digits) {
  let pro = digits.reduce((a, b) => a + b, 0);
  console.log(pro);

  while (pro >= 10) {
    ans = pro.toString();
    pro = 1;
    for (let i = 0; i < ans.length; i++) {
      pro = pro * ans[i];
    }
    console.log(pro);
  }

  return pro;
}
console.log(sumDigProd(16,28));

And crunching the code to a smaller footprint, it could become:

function sumDigProd(...digits) {
  let pro = digits.reduce((a, b) => a + b, 0);
  while (pro >= 10) {
    pro = Array.from(pro.toString()).reduce((a, b) => a * b, 1);
  }
  return pro;
}
console.log(sumDigProd(16,28));

Sign up to request clarification or add additional context in comments.

3 Comments

thanks it worked...but any case this can be done with while loop ?
can u update the code ? actually that was what i was looking for....with while loop..sorry that i didnt mention it clearly
Added to my answer.
2

You could return the result of calling calc for getting a recursive result.

function sumDigProd(...digits) {
    function calc(ans) {
        let pro = [...ans.toString()].reduce((a, b) => a * b);
        return pro > 9 
            ? calc(pro)
            : pro;
    }

    return calc(digits.reduce((a, b) => a + b, 0));
}

console.log(sumDigProd(16, 28)); // 6
console.log(sumDigProd(1, 2, 3, 4, 5, 6)); // 2

Comments

1

You just need to assign pro and change your while to an if:

function sumDigProd(...digits) {
  let ans = digits.reduce((a, b) => a + b, 0);
  console.log(ans);
  const result=calc(ans);
 function calc(ans) {
    ans = ans.toString();
    let pro = 1;
    for (let i = 0; i < ans.length; i++) {
      pro = pro * ans[i];
    }
    console.log(pro);
    if (pro >= 10) {
      pro = calc(pro);
    }
    return pro

  }
  return result
}
console.log(sumDigProd(16,28,12));

1 Comment

Ah, @trincot snuck in the same answer while I was composing mine!
1

A bit shorter version:

function sumDigProd(a, b){

  let rec = function(a) {
    if (String(a).length == 1) return a;
        return rec(String(a).split('').map(Number).reduce((a,b)=>a*b));
  }
   return rec(a+b);
}

Comments

0

Editorial: I found some of the answers here clever, but harder to follow, below is another example of adding the values, and then multiplying digits if there are multiple


Recursive: Product of Sum's Digits

const sumDigitProduct = (num,...rest)=>{

  if(rest.length)
    num = sumDigitProduct( rest.reduce((agg,cv)=>agg+parseFloat(cv), num) )
  
  const digits = (''+num).split('')
  if( digits.length > 1)
    num = sumDigitProduct( digits.reduce((agg,cv)=>agg*parseFloat(cv)) )
  
  return num;
};


// Tests
console.log('expect: 3; got:', sumDigitProduct(1,2))
console.log('expect: 5; got:', sumDigitProduct(15))
console.log('expect: 6; got:', sumDigitProduct(16,28))
console.log('expect: 0; got:', sumDigitProduct(0))
console.log('expect: 2; got:', sumDigitProduct(1,2,3,4,5,6))

1 Comment

Note, you don't really need recursion, this is forcing something that can easily be removed and function the same (if not more efficiently)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.