Anakin
Anakin

Reputation: 1291

Why does my loop gone infinite loop?

I am writing a function that will find prime factors of a number. In that function, it has got two loops. One for finding factors, another for finding prime factors from the first loop. The second loop has gone infinite, I haven't spotted anywhere in the loop that could make it infinite. Where did I miss?

function findPrimeFactors(num)
{
 var factors = [];
 var primeFactors = [];
 var currIndex = 0;
 var initFactorsLen;
 var currCompose;
 for (i = 1; i <= num; ++i)
 {
  if (num % i == 0)
  {
   factors.push(i);
  }
 }
 var initFactorsLen = factors.length;
 for (i = 0; i <= initFactorsLen; ++i) 
 {
 //This is infinite loop
  console.log("i is " + i + " and factors are " + factors);
  currCompose = factors[i];
  var primeTest = isPrime(currCompose); 
  if (primeTest == true)
  {
   primeFactors.push(currCompose);
  }
 }
 return primeFactors;
}

function isPrime(num)
{
 var sqrtNum = Math.sqrt(num);
 var ceiledNum = Math.ceil(sqrtNum);
 if (num == 1 || num == 0)
 {
  return false;
 }
 else if (num == 2)
 {
  return true;
 }
 else
 {
  for (i = 2; i <= ceiledNum; ++i)
  {
   if (num % i == 0 && i != num)
   {
    return false;
   }
  }
  return true;
 }
}

I've also notice that sometimes it doesn't gone infinite, but it returns only one prime number although it has 2. (Try findPrimeFactors(143))

Thanks,

Upvotes: 0

Views: 80

Answers (2)

PandaBlue
PandaBlue

Reputation: 361

I am not familiar with javascript... are you sure your 'i' is not shared by your loop in your two functions. What happens if you use 'k' as index in the function 'isprime'?

Never mind, it was solved 10 minutes ago

Upvotes: 1

Rick Hitchcock
Rick Hitchcock

Reputation: 35670

Your i loop variable is global, so both functions share the same values for i.

Initialize and declare it with var, like this:

for (var i = 0; i <= initFactorsLen; ++i)

An alternative to declaring it within the loop statement is to declare it with your other variables. Note that you can declare all your variables in a comma-separated list, like this:

var factors = [],
    primeFactors = [],
    currIndex = 0,
    initFactorsLen,
    currCompose,
    i;

Also note that you don't need to explicitly check for truthness. This:

var primeTest = isPrime(currCompose); 
if (primeTest == true) {
  primeFactors.push(currCompose);
}

… is equivalent to this:

var primeTest = isPrime(currCompose); 
if (primeTest) {
  primeFactors.push(currCompose);
}

… or more simply:

if (isPrime(currCompose)) {
  primeFactors.push(currCompose);
}

Upvotes: 4

Related Questions