Home > Software design >  For loop in which the counter goes up to a value generated by Math.floor()
For loop in which the counter goes up to a value generated by Math.floor()

Time:04-20

I'm a new web developer, been learning web dev for around 8-9 months. I recently became a mentor for new students in the bootcamp I graduated and I wanted to write a simple program to calculate all prime numbers up to a given upper limit. I have solved the exact same problem in C, C and Python. I am using the "naive" implementation, not the Sieve of Eratosthenes.

This is the code that works:

"use strict";

function primeNumbers() {
  let highNumber;

  highNumber = window.prompt("Calculate all prime numbers up to:");

  for (let i = 2; i <= highNumber; i  ) {
    let numberOfDivisors = 0;

    for (let j = 2; j < highNumber; j  ) {
      if (i % j == 0) numberOfDivisors  = 1;
    }
    if (numberOfDivisors == 1) console.log(i);
  }
}

Of course, j doesn't have to go all the way up to highNumber, as for any number, all possible divisors are less than half of the number. Thus, I changed the inside for loop making j only going up to Math.round(highNumber / 2 1):

"use strict";

function primeNumbers() {
  let highNumber;

  highNumber = window.prompt("Calculate all prime numbers up to:");

  for (let i = 2; i <= highNumber; i  ) {
    let numberOfDivisors = 0;

    for (let j = 2; j < Math.round(highNumber / 2   1); j  ) {
      if (i % j == 0) numberOfDivisors  = 1;
    }
    if (numberOfDivisors == 1) console.log(i);
  }
}

But this somehow breaks the code and causes unexpected results. I know all numbers are technically floating point numbers in JavaScript, but I thought that using Math.floor() would help me deal with that.

Any ideas on why this isn't working and what can be done? Thanks!

CodePudding user response:

Try this.

// Utility function to create a range starting from 2
const range = (num: number) => [...Array(num   1).keys()].slice(2);

const primeNumbers = (limit: number) => {
    // Create a range based on the limit
    const arr = range(limit);
    
    // Create an array for the prime numbers which will be returned.
    // Hardcode 1
    const prime: number[] = [1];

    // Loop through the range
    for (const x of arr) {
        // Create an array of divisors by filtering through
        // new range based on x
        const divisors = range(x).filter((num) => !(x % num));

        // If there is only 1 divisor and it === x, it is prime
        if (divisors.length === 1 && divisors[0] === x) prime.push(x);
    }

    return prime;
};

console.log(primeNumbers(50).length);

Here is the compiled TypeScript:

"use strict";
const range = (num) => [...Array(num   1).keys()].slice(2);
const primeNumbers = (limit) => {
    const arr = range(limit);
    const prime = [1];
    for (const x of arr) {
        const divisors = range(x).filter((num) => !(x % num));
        if (divisors.length === 1 && divisors[0] === x)
            prime.push(x);
    }
    return prime;
};
console.log(primeNumbers(50).length);

CodePudding user response:

A number always have two divisors, 1 and the number itself. j != i would ensure that an unnecessary computation does not takes place. I have initialized numberOfDivisors as 2 in the declaration. As we iterate, we check if numberOfDivisors increases any further. If so, that is not a prime number.

"use strict";

function primeNumbers() {
  let highNumber;

  highNumber = window.prompt("Calculate all prime numbers up to:");

  for (let i = 2; i <= highNumber; i  ) {
    let numberOfDivisors = 2;
    for (let j = 2; j < Math.round(highNumber / 2   1), j != i; j  ) {

      if (i % j == 0) numberOfDivisors  = 1;
    }
    if (numberOfDivisors == 2) console.log(i);
  }
}
  • Related