Intermediate Algorithm: Sum All Primes challenge

Intermediate Algorithm: Sum All Primes challenge
0

I procrastinated most of my day, but I was able to get back on the horse and work through this (my entire evening haha)

Usually i overwrite and comment, but I was able to spot my failing logic and pass the challenge - it can be further condensed im sure but here it is for now :laughing:

function sumPrimes(num) {
  let myArr = []; 
  let count = 0;
  for(let i =2; i<=num; i++){//all numbers 0 thru NUM
    //console.log("outer loop, index is", i);
    myArr.push(i);
    for(let n=2; n<=num; n++){//all numbers 2-NUM
 //     console.log(i%n===0, "n is ", n);
      if(i%n === 0 && i>n){
         console.log(i, ", there is a remainder! it is divisble!");
       count=1;
if(myArr.indexOf(i) > 0 && count>0){
  count=0;
//console.log(myArr);
 myArr.pop();
console.log(myArr);
}
      }//if
    };//inner loop
  };//outer loop
console.log("_ _f i n a l_ _ _ _a r r ay_ _ i s_ _, ".toUpperCase(), myArr);

let addPrimes = myArr.reduce((a,b)=> a+b);
return addPrimes;
return num;
}

console.log(sumPrimes(10));

Ah, in your second for loop make it:

for(let n=2; n<=i; n++)

and place your count variable before the second for loop, and declare it like this:

let count = 1;

so your final code should be:

function sumPrimes(num) {
  let myArr = []; 
  let count = 0;
  for(let i =2; i<=num; i++){//all numbers 0 thru NUM
    //console.log("outer loop, index is", i);
    myArr.push(i);
    let count=1;
    for(let n=2; n<=i; n++){//all numbers 2-NUM
      if(i%n === 0 && i>n){
         console.log(i, ", there is a remainder! it is divisble!");
        if(myArr.indexOf(i) > 0 && count>0){
          count=0;
          //console.log(myArr);
          myArr.pop();
          console.log(myArr);
        }
      }//if
    };//inner loop
  };//outer loop
  console.log("_ _f i n a l_ _ _ _a r r ay_ _ i s_ _, ".toUpperCase(), myArr);

  let addPrimes = myArr.reduce((a,b)=> a+b);
  return addPrimes;
  return num;
}

console.log(sumPrimes(10));

Also, please have a practice of indenting your code properly.

1 Like

Yeah my solution definitely could be better, I was just really happy to get through it haha

I thought my solution was poor, but honestly none of the other solutions here are easier to understand freeCodeCamp Challenge Guide: Sum All Primes

  let myArr = [];
  let count = 0;
  for (let i = 2; i <= num; i++) { //all numbers 2 thru NUM
 //console.log("outer loop, index is", i);
  	myArr.push(i);
  	for (let n = 2; n <= num; n++) { //all numbers 2-NUM
 //console.log(i%n===0, "n is ", n);
  		if (i % n === 0 && i > n) {
  			console.log(i, ", there is a remainder! it is divisble!");
  			count = 1;
  			if (myArr.indexOf(i) > 0 && count > 0) {
  				count = 0;
  				myArr.pop();
//console.log(myArr);
  			}
  		} //if
  	}; //inner loop
  }; //outer loop
  let addPrimes = myArr.reduce((a, b) => a + b);
  return addPrimes;
  return num;

Yeah, that’s fine when you’re learning. But in production, please be sure to follow standards and design patterns.

Also avoid using reduce as much as possible rather just use a for each loop.

Ballocks. It’s a fundamental part of functional programming. You can’t really comprehend Redux without grokking reduce for one thing.

1 Like

Hands down, the Sieve of Eratosthenes based solutions will give the fastest time to solution. I think it is also an interesting way to abstract the problem that helps you think about coding up problems more abstractly.

If you are interested, I can try to walk you though the basic idea.

2 Likes

Yes please, i found most of the solutions in the guide to be hard to read, and i think i saw some typos too :eyes:

Big picture, the idea behind the sieve is that a prime is not a multiple of any other number. This means that if you have a big list of numbers, you can find all of the primes by crossing off from that list all numbers that are multiples of others.

Suppose we want to find all of the primes below 10.

I’d make a list from 2 to 10 (1 is not prime).

numbers = [2, 3, 4, 5, 6, 7, 8, 9, 10]
isPrime = [1, 1, 1, 1, 1, 1, 1, 1, 1]

2 is the first number, and it hasn’t been crossed off, so it must be prime. However, any multiple of 2 cannot be a prime.

numbers = [2, 3, 4, 5, 6, 7, 8, 9, 10]
isPrime = [1, 1, 0, 1, 0, 1, 0, 1, 0]

3 is the next number, and it hasn’t been crossed off, so it must also be prime.

numbers = [2, 3, 4, 5, 6, 7, 8, 9, 10]
isPrime = [1, 1, 0, 1, 0, 1, 0, 0, 0]

4 is the next number, and it has been crossed off, so it must not be prime.

numbers = [2, 3, 4, 5, 6, 7, 8, 9, 10]
isPrime = [1, 1, 0, 1, 0, 1, 0, 0, 0]

5 is the next number, and it has not been crossed off, so it must be prime.

numbers = [2, 3, 4, 5, 6, 7, 8, 9, 10]
isPrime = [1, 1, 0, 1, 0, 1, 0, 0, 0]

and so on…

This is hands down, the fastest way to find a list of prime numbers from 1 to n.

You don’t really need two arrays: you can just use the array index and add 2 (or just put 0 and 1 in the input array and skip them), then start setting multiples that you cross off to null or undefined or whatnot. Then in JS you can just test the array elements for truthiness

Sieve is a classic example of dynamic programming where you keep state “as you go”, typically in an array. As a functional programmer, the imperative state updates bug the hell out of me, but a pure-functional sieve turns out to be a surprisingly tricky problem to do efficiently.

1 Like

Yeah, the numbers array is superfulous. I just added it to make the explanation easier to follow.

No, all I am saying is not using it where you could use something else more readable. As given in the video, there is no problem using reduce for getting something done and is the only solution, or is more readable than it’s alternatives. The video is also made in a fun way, it’s obvious they are not being completely serious about it.

There are some cases where I have gotten carried away using anonymous functions, reduce, and other es6 features, nested callback functions, etc and then end up with a whole lot of spaghetti code.

If you are aware of readability issues, and you know that reduce is a good option, then go ahead. It’s all I am saying.

And yeah, I should have been more clear in my initial comment. I made a blunt statement

I don’t see any option to reply in the main thread, so i will just leave it here.
This is my solution. I think it’s more easier to read and short and efficient.

function sumPrimes(num) {
  //Flag all non-primes with 1 in prime array.
  let prime = new Array(num+1).fill(0); //array of zeroes 
  for(let i=2; i*i<=num; i++){
    for(let j = i*i; j<=num; j+=i){
        prime[j] = 1;  //marking non-primes with 1
    }
  }

  //calculate sum
  let sum = 0;
  for(let i=2; i<=num; i++){
      if(prime[i]===0) sum+=i;    //all non-prime locations are marked with 1
  }
  console.log(sum);
  return sum;
}

sumPrimes(977);

I’d flip the flagging from 1 to 0 so you can use prime[i] as your condition, but I think your solution is overall pretty clean.