1

For a function that takes an integer n and returns an array of the first n primes, we have:

function nPrimes(n) {
    let primes = [];
    for(let i = 3; primes.length < n - 1; i += 2) {
        if (primes.every(prime => i % prime !== 0)) {
            primes.push(i);
        }
    }
    primes.unshift(2);
    return primes;
}

I'm not sure what the complexity of this algorithm would be. It seems at least quadratic, because the every call adds one n to the runtime complexity where n is the size of the primes array at a given iteration. The unshift at the end adds an n but is irrelevant because it will be dwarfed by the leading coefficient.

The follow up is, is there a more efficient way of generating such an array?

Marc Fletcher
  • 932
  • 1
  • 16
  • 39
  • For faster solutions, I recommend reading up on the [sieve of eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes). – ShadowRanger Jul 15 '18 at 21:11

1 Answers1

0

This computation is quite arduous.

The outer loop is executed n times and invokes the every construct for all odd numbers from 3 to the nth prime.

If the every construct indeed tests all the primes in the list so far, the total workload will be proportional to the sum of k.(P[k+1]-P[k]) = k.G[k] where P[k] is the k-th prime and G[k] the gap until the next prime (when the k-th prime has been found, the list has k elements and is tested until the next prime).

By the prime number theorem, we know that the "average" gap length is on the order of log P[k], itself on the order of log(k log k) = log k + log log k. Then the summation yields O(n.log n).

Now if the every construct stops as soon as it meets a false condition, its cost is reduced. In fact, the search will stop at the first prime factor of the tested number, and the total workload will be proportional to the sum of the indexes of the first prime factors of all odd numbers up to P[n] ~ n log n.

From Web search, it appears that the distribution of the first prime factor of the integers follows a law in 1 / P[k] log P[k], for the k-th prime, i.e. 1 / k.log k.log(k.log k), and we need to sum over all integers m, using k ~ m / log m. Neither very rigorous nor easy.

  • Note that your solution is inefficient as it stands, because it is enough to try divisors up to `√i` only, which drastically reduces the number of attempts. –  Jul 15 '18 at 21:33