FCC Bonfire Series 131: Sum All Prime

Today, we tackle a new challenge. This time, we are going to start simple, and then challenge our brains to optimize our function a little. I won’t be giving you the fastest answer to this problem, but I’ll do my best to get you on the right track.

This bonfire, Sum All Primes, will have us do exactly that (we do not need to sum Optimus Prime and his whole family). Given a number, we must sum all of the prime number up to it (the given number may not be prime by the way!). To ease this problem, we are going to take one step at a time. First, we need to figure out how to make sure that a number is indeed a prime number.

We know a number is prime when it has only two divisors, them being 1 and itself (we do not consider 1 to be a prime number). For example, 2, 3 and 5 are prime numbers. Some of you may be thinking about a way of detecting prime numbers already:

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

That kind of works, but it will fail when we give it 0 or 1, let’s fix that:

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

We know that no number is divisible by any number greater than itself divided by 2. For example, 10 is divisible by 1, 2 and 5, but we don’t even need
to think if it would be divisible by 6, 7, 8 or 9, since we know it’s not possible. How about having our for loop stop checking once we reach that point?

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

Now we’ve got a function that given a number, checks if it’s prime or not, let’s start with the actual bonfire! I’ll refresh your memory, we need to sum every prime number that is below the number given as an argument, and return it. Our isPrime function is ready to go, so let’s use it! We’ll create a variable for the final result and set it to 0, then use a for loop to go over every integer between 0 and the given number, and add it to our result variable if they are a prime number.

function sumPrimes(number) {
  var result = 0;

  for (var i = 0; i <= number; i++) {
    if (isPrime(i)) {
      result += i;
    }
  }

  return result;

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

That seems great! And it will even pass every test! But it’s doing some unneccesary work. While checking for prime numbers, we are actually testing every even number along the way, and the only prime even number is 2. We can change the isPrime function to discard even numbers and return false, and that’s great, but we  would still be testing each one of them. Why don’t we skip them entirely in the for loop? Instead of incrementing i by one at every loop, let’s do it by 2! We’ll have to change a few things to get it to work, but it will be much faster once we are done:

function sumPrimes(number) {
  if (number < 2) { // If the given number is less than 2, return 0 without doing anything else.
    return 0;
  }

  var result = 2; // Initialize result as 2, since we are going to start our loop at 3 and increment by 2, testing only odd numbers.

  for (var i = 3; i <= number; i += 2) {
    if (isPrime(i)) {
      result += i;
    }
  }

  return result;

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

You should be good to go! There is so many ways for you to change this function and make it your own. Try using the reduce method with an array of prime numbers for example, I’ll leave an example below for those interested!

function sumPrimes(number) {
  if (number < 2) return 0;
  var result = [2];

  for (var i = 3; i <= number; i += 2) {
    if (isPrime(i)) result.push(i);
  }

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

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

Code much, and fail often, for mistakes are what carves knowledge into our brains!