3

I am working on an excercise to sum all prime numbers from 2 to the parameter. I have worked this far in the code, but am stuck. I believe by using the splice function, I am actually skipping an element because of a changed indices.

function sumPrimes(num) {
  var primearray = [];
  var sum = 0;
  for(var i =2; i <= num; i++){
    primearray.push(i);
  }

  for(var j = 0; j < primearray.length; j++) {
    console.log(primearray[j]);
    if ((primearray[j]%2===0) && (primearray[j] >2)) {
      primearray.splice(j,1);
    } else if ((primearray[j]%3===0) && (primearray[j] > 3)) {
      primearray.splice(j,1);
      console.log(primearray);
    } else if ((primearray[j]%5===0) && (primearray[j] > 5)) {
      primearray.splice(j,1);
    } else if ((primearray[j]%7===0) && (primearray[j] > 7)) {
      primearray.splice(j,1);
    }
  }
  sum = primearray.reduce();
  return sum;
}

sumPrimes(30);

I haven't utilized the reduce function yet because I am still working on the if else statements.

Eric Park
  • 502
  • 2
  • 7
  • 23
  • 6
    It's rarely a good idea to mess with a collection while you are trying to iterate over it. Why not check if a number is prime *before* you push it on the array? – Matt Burland Jun 24 '15 at 16:37
  • [How to find prime numbers between 0 - 100?](http://stackoverflow.com/q/11966520/1456376) in JavaScript – insertusernamehere Jun 24 '15 at 16:38
  • ^ What Matt said. I think you can fix the problem just by decrementing `j` when you splice something from the array. But I don't see why you're doing it this way. It's not going to scale at all. – bbill Jun 24 '15 at 16:38

13 Answers13

5

I found a pretty good solution to the same problem. afmeva was spot on. This is how it works.

function isPrime(val){

  //test if number is prime
  for(var i=2; i < val; i++){
    if(val % i === 0){
      return false;
    }
  }
  return true;
}

In the above code we accept a number to determine whether or not it is prime. We then loop from two all the way up until our number minus one because we know that our number will be divisible by itself and one. If the remainder of our value with the current loop value is zero then we know it is not prime so break out and say so.

This article explains very well

function sumPrimes(num) {
  var answer = 0;

  //loop through all numbers from 2 to input value

  for(var i=2; i <= num; i++){   

    //sum only prime numbers, skip all others
    if(isPrime(i)){
      answer += i;
    }
  }
  return answer;
}

sumPrimes(977); // 73156

Here's another good resource

  • 2
    You can optimize isPrime function to reduce the number of loop iterations by only checking factors from 2 to val/2 (inclusive), since one factor will have to be less than half the value of the number and the matching factor is not necessary to find. For example, num = 12, isPrime only needs to iterate from 2 to 6 to find all of the factors and of course will break on 2 the first factor. For large num, this will reduce the number of iterations substantially. `function isPrime(val){ for(var i=2; i <= val/2; i++)` – NJITman Jun 04 '20 at 14:09
2

function sumPrimes(num) {
    let arr = Array.from({length: num+1}, (v, k) => k).slice(2); 
  
  let onlyPrimes = arr.filter( (n) => { 
    let m = n-1;
    while (m > 1 && m >= Math.sqrt(n)) { 
      if ((n % m) === 0) 
        return false;
        m--;
    }
      return true;
  });
    return onlyPrimes.reduce((a,b) => a+b); 
}
sumPrimes(977);
Iffy
  • 79
  • 1
  • 6
2

I have seen lots of people putting all prime numbers into arrays and in order to check if a number is prime, they check from 2 to the number to see if there's a remainder. You only need to check odd numbers, and only need to count to half the number because a number can't be divisible by any number greater than it has. Here's my solution:

function sumPrimes(num){
    var sum = num>=2?2:0;
    for(var i=3;i<=num;i+=2){
        var isPrime=true;
        for(var j=3;j<(i/2);j++){
            if (i%j==0)
            {
                isPrime=false;
                break;
            }
        }
        sum+=isPrime?i:0;
    }
    return sum;
}

Note: I started from j=2 because we are only checking odd numbers, so they'd never be divisible by 2.

jstack123
  • 55
  • 7
1
function sumPrimes(num) {
  var sumArr= [];
  for(var i=0;i<=num;i++){
    if(isPrime(i))
      sumArr.push(i);
  }

  sumArr = sumArr.reduce(function(a,b){
    return a+b;
  })

  return sumArr;
}

function isPrime(num) {
    if(num < 2) return false;
    for (var i = 2; i < num; i++) {
        if(num%i === 0)
            return false;
    }
    return true;
}

sumPrimes(10);
0

something like this?

function isPrime(_num) {
 for(var i = 2; i < _num; i++) {
  if(!(_num % i)) {
   return false
  }
 }
 return true;
}


function sumPrimes(_num) {
 var sum = 0;
 for(var i = 2; i <= _num; i++) {
  if(isPrime(i)) {
   sum += i;
  }
 }
 return sum;
}

sumPrimes(20) // 77
sumPrimes(5) // 10
afmeva
  • 839
  • 7
  • 13
0

You could do this as well.

function sumPrimes(num) {
    var sum = 0;
    for (var i = 0; i <= num; i++) {
        if (isPrime(i)) {
            sum += i;
        }
    }
    return sum;
}

function isPrime(n) {
    if (n < 2) { return false; }
    if (n !== Math.round(n)) { return false; }
    var result = true;
    for (var i = 2; i <= Math.sqrt(n); i++) {
        if (n % i === 0) {
            result = false;
        }
    }
    return result;
}
saga
  • 26
  • 5
0

Here's my solution. I hope you find it easy to interpret:

function sumPrimes(num) {

  // determine if a number is prime
  function isPrime(n) {
    if (n === 2) return true;
    if (n === 3) return true;
    if (n % 2 === 0) return false;
    if (n % 3 === 0) return false;

    var  i = 5;
    var  w = 2;
    while (i * i <= n) {
        if (n % i === 0) {
            return false;
        }
        i += w;
        w = 6 - w;
    }
    return true;
  }

  // subtract 1 for 'not being prime' in my context
  var sum = isPrime(num) ? num - 1 : -1;

  for (var x = 0; x < num; x++) {
    if (isPrime(x) === true) {
      sum += x;
    }
  }

  return sum;
}
Yup.
  • 1,883
  • 21
  • 18
0

here is my solution to sum of n prime number

function sumOfNPrimeNumber(num){
 var sum = 0;
 
 const isPrime = function(n){
  if (isNaN(n) || !isFinite(n) || n%1 || n<2) {
   return false;
  }

  if (n%2==0){
   return (n==2);
  }

  var sqrt = Math.sqrt(n);
  for (var i = 3; i < sqrt; i+=2) {
   if(n%i == 0){
    return false;
   }
  }

  return true;
 }

 const getNextPrime = function* (){
  let nextNumber = 2;
  while(true){
   if(isPrime(nextNumber)){
    yield nextNumber;
   }
   ++nextNumber;
  }
 }

 
 const nextPrime = getNextPrime();
 for (var i = 0; i < num; i++) {
  sum = sum + nextPrime.next().value;
 }

 return sum;
}

console.log(sumOfNPrimeNumber(3));
ganesh phirke
  • 471
  • 1
  • 3
  • 12
0

All the above answers make use of helper functions or aren't time efficients. This is a quick, recursive solution in O(n) time:

// @ signature int -> int
// @ interpr: returns sum of all prime integers <= num
// assume: num is positive integer

function sumPrimes(num) {
  if (num <= 2) {
    return 2;
  }

  let i = 2;
  while (i < num) {
    if (num % i === 0) {
      return sumPrimes(num - 1)
    }
    i++;
  }
  
  return num + sumPrimes(num - 1)
}

// test
sumPrimes(10); // -> 17
rags2riches-prog
  • 1,663
  • 1
  • 10
  • 22
0
function prime_sum(num){
let count=0;        *//tracks the no of times number is divided perfectly*
   for(let i=1;i<=num;i++){        *//from 1 upto the number*
      if(num%i==0){count++};
}
if(count===2){return "Prime"};
return{"Not prime"};
}
console.log(prime_sum(10));//expected output is 17**

//the code receives a number,checks through the range and returns prime if it meets the condition

0

The following solution uses the Eratosthenes Sieve to sum all prime numbers lower than or equal to num. The first for loop fills an array with size equal to num with true. The second for loop sets to false all non-prime numbers in the array. Then, the last for loop simply iterates through the array to sum all the array indexes i for which the value in the array, i.e., array[i], is equal to true.

/**
 * Sum all primes lower or equal than n.
 * Uses the Eratosthenes Sieve to find all primes under n.
 */
function sumPrimes(num) {
  let array = [];
  let output = 0;

  // Fill an array of boolean with 'true' from 2 to n.
  for (let i = 0; i <= num; i++) {
    array.push(true);
  }

  // Set all multiples of primes to 'false' in the array.
  for (let i = 2; i <= Math.sqrt(num); i++) {
    if (array[i]) {
      for (let j = i * i; j <= num; j += i) {
        array[j] = false;
      }
    }
  }

  // All array[i] set to 'true' are primes, so we just need to add them all.
  for (var i = 2; i <= num; i++) {
    if (array[i]) {
      output += i;
    }
  }

  return output;
}

console.log(sumPrimes(10)); // 17
console.log(sumPrimes(977)); // 73156
console.log(sumPrimes(250_000_000)); // 197558914577
cesarsotovalero
  • 1,116
  • 6
  • 15
0

function sumPrimes(num) {
  let output = 0;
  // check if num is a prime number
  function isPrime(num) {
    for(let i = 2; i < num; i++) {
      if(num % i === 0) {
          return false;
        }
      }
      return true;
    }
      for (let i = 2; i <= num; i++) {
        if (isPrime(i)) {
          output += i;
        }
      }
      return output;
    }
    
console.log(sumPrimes(10)); // 17
-1

This is what I've done to get primes. I don't know if it's the most efficient, but it works. This is in Java, but can be easily converted to JavaScript. Hopefully this will help point you in the right direction.

final int TOTAL = 10;
int primes[] = new int[TOTAL];
int arrPos = 2;
boolean prime = false;
primes[0] = 2;

for (int i = 2; i < TOTAL; i++) {
  prime = false;
  int sqrt = (int) Math.sqrt(i);
  for (int j = 1; j < arrPos && primes[j] < sqrt; j++) {
    if (i % primes[j] != 0) {
      prime = true;
    } else {
      prime = false;
      break;
    }
  }

  if (prime == true) {
    primes[arrPos] = i;
    arrPos++;
  }
}
imtheman
  • 4,713
  • 1
  • 30
  • 30
  • I would only make a slight change to this, in the inner loop it is not necessary to go all the way through the current list of primes, only up to the square root of the number you are checking, so change it to... for (int j = 1; j –  Jun 24 '15 at 16:41
  • @Gilchrist Ah, thank you. I've never thought about that before. – imtheman Jun 24 '15 at 16:45
  • And I would use a list instead of an array, so I wouldn't have to worry about keeping a separate arrPos and allocating an array that will have more elements than I will need. –  Jun 24 '15 at 16:47
  • @Gilchrist I agree with you, but when `TOTAL` is small it doesn't really matter. – imtheman Jun 24 '15 at 16:56
  • @TomDDD Thanks for catching that. – imtheman Jun 24 '15 at 19:26