dan brown
dan brown

Reputation: 323

Javascript while loop count higher than expected

I'm writing a function which takes in a positive number and returns the number of times you must multiply the digits in num until you reach a single digit.

example:

test(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
                   // and 4 has only one digit//if single digit return num

The code:

function test(num) {
if (num > 10) { return num} else {
   var j = num;var a;var count = 0;
while ( j > 10){
   a = num.toString().split('').map( e=> parseInt(e)).reduce((a,c)=> a*c);
   num = a;
   count++;
   j--; 
   }  
return count;
}}

test(39) //outputs 29 expected 3;

I have fixed the above by adding an array and filtering for unique values but would still like to know why the code is giving me a much higher count than expected.

Upvotes: 0

Views: 240

Answers (4)

ACD
ACD

Reputation: 1431

You decremented your num by 1 each iteration. It gives you 29 because 39 - 10 is 29. You didn't update the actual num which you need to compare if it's still greater than 10.

Do this instead:

function test(num) {
  if (num < 10) {
    return num
  } else {
    var count = 0;
    while (num > 10) {
      num = num.toString().split('').map(e => parseInt(e)).reduce((a, c) => a * c);
      count++;
    }
    return count;
  }
}

console.log(test(39))

Upvotes: 0

Bogdan
Bogdan

Reputation: 399

You're decrementing j, which is initially 39. It will reach 10, then it will return the number of times it was decremented (29 times, which coincides with your result). You need to do the following, assuming the split part is correct:

function test(num) {
if (num < 10) { return num} else {
   var j = num;var a = 11; // just to enter the while loop at least once
   var count = 0;
while ( a > 10){
   a = num.toString().split('').map( e=> parseInt(e)).reduce((a,c)=> a*c);
   num = a;
   count++;
   j--; 
   }  
return count;
}}

Upvotes: 0

Anubrij Chandra
Anubrij Chandra

Reputation: 1442

Correction in your code, you can compare

    function test(num) {
if (num < 10) { return num} else {
   var a;var count = 0;
while ( num > 10){
   a = num.toString().split('').map( e=> parseInt(e)).reduce((a,c)=> a*c);
   num = a;
   count++;

   }  
return count;
}}

test(39) //outputs 3;

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370979

You might be looking to use recursion here - if the num is smaller than 10, return 0, otherwise, perform the needed multiplication, and then return 1 + the result of calling test on the product:

function test(num) {
  return num < 10
  ? 0
  : 1 + test(
    num.toString().split('').reduce((a, c) => a * c)
  )
}

console.log(test(39));

(note that * will coerce strings to numbers already, no need for parseInt)

Upvotes: 2

Related Questions