Leed
Leed

Reputation: 303

Prime number, need a little assistance

Background Information:

So am trying to calculate all the prime numbers inside a number, and then sum them up. sumPrimes(10) should return 17 because 2 + 3 + 5 + 7 = 17.

The challenge is here --> https://www.freecodecamp.org/challenges/sum-all-primes

I added some console.log's in just to show whats happening.


My Approach:

My approach to doing this was trying to replicate this tutorial here but in code: https://youtu.be/FBbHzy7v2Kg?t=67

What i tried with my code was to separate the number into a array from 2, to what ever your number is (1 isn't prime). 10 would look like [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ]. Then i use another for loop with i to pick a number out of that previous array arr, add it to prime, and then remove every multiple of that number from the array (arr) using a separate loop. When i go back to go get another number, we already know its a prime.

The rest of this is if you don't understand.


Example:

The first number of that array is 2. So i add 2 to prime.

prime's current value: 2

And then filter out any multiple. Since i am counting by the number itself in my j loop, i already know any number is a multiple. It also removes my already prime number from the array along with all its multiple's so it would never be undefined.

arr's current value (hopefully): [ 3, 5, 7, 9]

etc (continues on with 3, 5, and then 7).


Whats going wrong?

Its not removing all the multiples. I am using splice, and i don't think its cutting out that number correctly. Help?

Please don't just give me some ES6 answer and walk away. I want to stick with my (well the video's) idea. I don't care how short your answer is, just whats wrong with mine.


The repl --> https://repl.it/@John_Nicole/prime

function sumPrimes(num) {

    var prime = 0;
    var arr = [];


    for (let i = 2; i <= num; i++) {
        arr.push(i);
    } // turns into array
    console.log(arr)


    for (let i = 0; i < arr.length; i++) {
        var number = arr[i];
        console.log("Prime: "+prime+"+"+number)
        prime+=number


        for (var j = number; j <= arr.length; j+=number) {
          arr.splice(j)
        } // j

    } // i


   return "Final result: "+prime;
}

sumPrimes(10);

Thanks in advance :D

Upvotes: 4

Views: 191

Answers (1)

Kaiser Dandangi
Kaiser Dandangi

Reputation: 230

As everyone has already pointed out, your expectation of splice() seems incorrect. Check out the MDN docs here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

>>> [1,2,3].splice() # Input
>>> []               # Output

There are two problems:

  1. The function is not removing the value (from arr) correctly
  2. The looping logic for the filter doesn't take into account the changing length of the array when you remove a value

This is how you could use splice to remove a value:

This creates a copy of the array starting at the index right after the one you want to take out

arrayTail = arr.slice(j + 1);

This extracts all the elements in the array from the start till the index just before the one you want to take out

arrayHead = arr.splice(0,j);

Finally merge the two pieces together to get your filtered array

arr = arrayHead.concat(arrayTail);

Alternatively, you could also use the Array.filter function:

arr = arr.filter(function(value){
    // Filter all values that are divisible by the prime
    return value % number != 0;
});

For part two, consider:

arr = [1,2,3,4,5,6,7,8,9];
// You filter for multiples of 2
// And that's okay because all the values are indices offset by 2
arr = [1,2,3,5,9];
// You filter for multiples of 3
arr[2] == 3
arr[4] == 9
// But the multiples of 3 are no longer offset by 3

So instead of being clever about indices, simply loop through the rest of the array as normal, and just check whether the current value is a multiple of the prime number or not.

if (arr[j] % number == 0) {
    ... your splice code
}

Now, this might be unsolicited, it sounds like you are just learning to program. I highly recommend developing a habit of using full variable names so it is easy to read. And also including a lot of comments to highlight the logic you are trying to accomplish by that coding block.

Hopefully you find this a good example:

function sumPrimes(num) {

    var currentPrime = 0;
    var arr = [];
    var sumOfPrimes = 0;

    // Create an array of potential primes
    for (let i = 2; i <= num; i++) {
        arr.push(i);
    }
    console.log("Prime array", arr);

    // For every value in the array, remove any future multiples of it
    for (let i = 0; i < arr.length; i++) {
        var currentPrime = arr[i];
        console.log("Prime: " + currentPrime);

        sumOfPrimes += currentPrime;
        console.log("Sum of Primes: " + sumOfPrimes);

        // Remove multiples of prime
        // Start at the next value in the array
        // And loop till the end
        for (let j = i + 1; j < arr.length; j++) {
            // If the current value is a multiple of
            // the prime, then remove it
            if (arr[j] % currentPrime == 0) {
                arrayTail = arr.slice(j + 1);
                arr = arr.splice(0,j).concat(arrayTail);
                j -= 1;
                // Since you removed an element, you need to
                // move the index back so it doesn't skip
                // any checks
            }
        }

        console.log("Filtered array for ", currentPrime, arr);

    }

   return "Final result: " + sumOfPrimes;
}

Upvotes: 1

Related Questions