Home > Net >  While loop with two nested for loops outputting infinite loop, what am I doing wrong?
While loop with two nested for loops outputting infinite loop, what am I doing wrong?

Time:02-16

I am making a program that takes any random integer add up its individual values and create a sum. If the length of the sum when converted to string form is greater than 1, we continue the process of adding the integer values together until we reach a sum with 1 digit.

My issue with the code is that my expected output for random numbers with a value of 1 digit already will return the number immediately, if the numbers with digits greater than 1 add up to another greater than 1 digit number, it will not repeat the loop but rather be stuck in an infinite loop.

  let digitalRoot = (n) => {
  let stringNum = n.toString();
  let refArr = [];
  let result = 0;
  let iterator = refArr.values();
  while (stringNum.length > 1) {
    for (let i = 0; i < stringNum.length; i  ) {
      let stringVal = stringNum[i];
      stringVal = parseInt(stringVal);
      refArr.push(stringVal)
    }
    for (let number of iterator) {
      if (result !== number) {
        result = result   number;
      }
      else {
        result = result   number;
      }
    }
    result = result.toString();
    if (result.length === 1) {
      result = parseInt(result);
      return result;
    }
    refArr = [];
    stringNum = result.toString();
  }
  if (stringNum.length === 1) {
    stringNum = parseInt(stringNum);
    return stringNum;
  }
}

expected output for 1455 for example should be 6, because 1 4 5 5 = 15; 1 5 = 6

thank you so much for any help :)

CodePudding user response:

You can do that...

const digitalRoot = n =>
  {
  while (n > 10)
    n = [...n.toString(10)].reduce((s,v)=>s    v,0)
  return n  
  }

console.log( digitalRoot( 1455 ))

CodePudding user response:

What happens if n is negative? Let's assume n >= 0 for this. It's really unclear why you have 2 loops, and the 2nd one has a test for something but does the same thing regardless.

  • In general, try to avoid making the same variable sometimes a number and sometimes a string. "15" 1 = "151" while 15 1 = 16
  • Reset your accumulators at the start of loops.
  • Rarely a need to grab the iterator before the loop

A simplified version:

let digitalRoot = (n) => {
  while (n >= 10) {
    // convert to decimal
    let stringNum = n.toString();
    let result = 0
    for (let i = 0; i < stringNum.length; i  ) {
      result  =  parseInt(stringNum[i]);
    }
    n = result
  }
  return n
}

CodePudding user response:

Much simpler way would be to use reduce(), this higher function iterates over an array of values and reduces the number of those values with each iteration while calculating the accumulated previous value with the next value in the array.

Split the string into an array, then map it back to a Number and reduce adding the accumulator to the return value each iteration.

const num = 1455;
const num2 = 35714;
const num3 = 11211;

const sumUp = (num) => { 
  return String(num).split('').map(Number).reduce((a,c) => a c) 
  }  

console.log(sumUp(num), sumUp(num2), sumUp(num3))

  • Related