First time poster here. I’m having a little trouble with the Sum All Primes challenge. My code works for smaller numbers like 10, 100, etc.; however, when I try a number like 977 I get the following error message along with an incorrect sum result:

“Potential infinite loop detected on line 30. Tests may fail if this is not changed.
56690”

I’m specifically looking for help determining what is causing the potential infinite loop. Any help would be appreciated, thanks!

My Code So Far

function sumPrimes(num) {
//Create function to detect if a number is prime -- if number has more than 2 factors it is not prime
function isPrime(indexNum){
let arr = [];
for (let i = 1; i <= num; i++){
if (indexNum % i == 0){
arr.push(i);
}
}
if (arr.length <= 2 && indexNum !== 1) {
return true;
}
}
//Create an array of numbers less than or equal to one
//Then loop throught the array and check if each number is prime
let numArr = [];
let newNumArr = [];
let result = 0;
for(let j = 0; j <= num; j++){
numArr.push(j);
}
//If its prime, push the prime number into the new array
for (let k = 0; k < numArr.length; k++) {
if (isPrime(numArr[k]) == true) {
newNumArr.push(numArr[k]);
}
}
//sum the prime numbers
for (let l = 0; l < newNumArr.length; l++){
result += newNumArr[l];
}
console.log(result);
return result;
}
sumPrimes(977);

Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36

Don’t I need to make sure any given number in the sequence up to the given number has no other divisor other than itself?

My intent was to check each number in the array up to num for more than 2 divisors.

I did modify the code using your suggestion, but it didn’t sum up right and it’s not helping the possible infinite loop issue (I am more concerned about this).

I highlighted specifically the loop inside of your isPrime function. If you find a divisor that is not 1 or indexNum, then indexNum is not prime.

You are getting a infinite loop warning because your code is too slow. Fixing your isPrime function will help with this, and fixing that loop to not create an array is the first step of fixing your isPrime function.

What is your updated code? I can’t really understand what you changed very well without seeing your code.

Well, after trying to modify per the suggestion, I couldn’t get it to work; however, I did end up finding the main issue - not referencing my indexNum argument:

This:

for (let i = 1; i <= **num**; i++){
if (indexNum % i == 0){
arr.push(i);
}
}

Should be:

for (let i = 1; i <= **indexNum**; i++){
if (indexNum % i == 0){
arr.push(i);
}
}

Works just fine now. Feel so foolish lol - spent a long time on that one for a silly mistake.

I am interested in seeing how you would change the portion that you were talking about though. I attempted but couldn’t get it to work.

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

Good job figuring it out! You have lots of room to make this faster.

Ok, there are two rules of thumb for fast code (these end up being pretty good rules of thumb for clear, maintainable code as well)

Don’t compute more than you need

Don’t store more than you need

Your code violates those rules of thumb in a couple of places.

//Create function to detect if a number is prime -- if number has more than 2 factors it is not prime
function isPrime(indexNum) {
let arr = [];
for (let i = 1; i <= num; i++) {
if (indexNum % i == 0) {
arr.push(i);
}
}
if (arr.length <= 2 && indexNum !== 1) {
return true;
}
}

This violates rule 1 and rule 2.

Divisors come in pairs. If a number indexNum is divisible by 3, then it is also divisible by indexNum/3. This means you are checking way more numbers than you need to.

You don’t need to store what the divisors are. You only need to know if indexNum % i is true for any potential divisors other than 1 and indexNum.

//Create an array of numbers less than or equal to one
//Then loop throught the array and check if each number is prime
let numArr = [];
let newNumArr = [];
let result = 0;
for (let j = 0; j <= num; j++) {
numArr.push(j);
}

This code violates rule 2.

You don’t need to store all numbers between 1 and num to be able to check if which numbers are prime.

//If its prime, push the prime number into the new array
for (let k = 0; k < numArr.length; k++) {
if (isPrime(numArr[k]) == true) {
newNumArr.push(numArr[k]);
}
}
//sum the prime numbers
for (let l = 0; l < newNumArr.length; l++) {
result += newNumArr[l];
}

This code violates rules 1 and 2.

Why make a separate loop to sum the contents of newNumArr? Separate loops over the same values means you do more work.

Why store the prime numbers? You only need the sum of the prime numbers.

I see what you mean and really appreciate the feedback! Originally, I had stored the items to log them to check if my logic was correct.

Would you mind showing me what my code streamlined would look like? I’m just interested in seeing an example as I would really like to apply your rules to future code. An example sure would help cement it for me!

I’d recommend trying trying to do it and asking questions here if you get stuck, but if you want to jump to looking at the answers, I wrote the solutions on the hints page, so anything I write here would look just like that! (Expanded version of Solution 3 found here: JavaScript Performance Measurement & Variability)