Reputation: 584
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
Upvotes: 2
Views: 163
Reputation: 1327
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
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))
Upvotes: 0
Reputation: 386550
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
Upvotes: 2
Reputation: 350137
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));
Upvotes: 5
Reputation: 326
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);
}
Upvotes: 1
Reputation: 7305
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));
Upvotes: 1