Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: trekhleb/javascript-algorithms
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: sanxsth/javascript-algorithms
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: linear-prime-sieve
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 8 commits
  • 3 files changed
  • 2 contributors

Commits on Sep 24, 2018

  1. Add linear prime sieve

    sandeeps456 committed Sep 24, 2018
    Copy the full SHA
    01f1408 View commit details
  2. Adds README.md

    sandeeps456 committed Sep 24, 2018
    Copy the full SHA
    786cd38 View commit details
  3. Copy the full SHA
    65037f3 View commit details

Commits on Oct 1, 2018

  1. Copy the full SHA
    b437388 View commit details
  2. Copy the full SHA
    49bdb35 View commit details
  3. Copy the full SHA
    66f0766 View commit details

Commits on Jan 26, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1d378ae View commit details

Commits on Jan 13, 2020

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7fd168d View commit details
44 changes: 44 additions & 0 deletions src/algorithms/math/linear-prime-sieve/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Linear Prime Sieve

Linear Prime Sieve is an algorithm for finding all prime numbers up to some limit `n` in linear time.



## How it works

1. Create an array `leastPrimeFactor` of `n + 1` positions filled with `0`(to represent the least prime factors of numbers `0` through `n`)
2. Start at position `i = 2` (the first prime number)
3. If the least prime factor of `i` is `0` it means `i` is a prime number, so we add it to our list of `primes`.
4. We start setting the least prime factor for numbers `x`, where x = `p` * `i`, `p` is `x`'s least prime factor and `p` <= `leastPrimeFactor(i)`, we do
this by traversing the list of primes accumulated till now.
5. Increment the value of `i`.
6. We repeat steps 3 through 5 until `i` exceeds `n`.


When the algorithm terminates, all the prime numbers from `0` through `n` will be added to our primes list



## Complexity

The algorithm has a complexity of `O(n)`.



## Proof Of Correctness

In order to prove the time complexity, we need to show that the alogrithm sets all leastPrimeFactor[] correctly, and that every value will be set only once.
If so the algorithm will have linear time complexity, since all the remaining work of the algorithm is of `O(n)`.
We Observe that every number `i` has exactly one representation of form:
`i = leastPrimeFactor[i] * x`, where leastPrimeFactor[i] <= leastPrimeFactor[x].

In our Alogrith, for every `x`, it goes through all prime numbers it could be multiplied by, i.e. all prime numbers up to leastPrimeFactor[x] inclusive,
in order to get the numbers in the form given above.
Hence, the algorithm will go through every composite number exactly once, setting the correct values for leastPrimeFactor[] there.



## References

- David Gries, Jayadev Misra. A Linear Sieve Algorithm for Finding Prime Numbers [1978].
- [CP-Algorithms/Linear-Sieve](https://cp-algorithms.com/algebra/prime-sieve-linear.html).
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import linearPrimeSieve from '../linearPrimeSieve';

describe('linearPrimeSieve', () => {
it('should find all primes less than or equal to n', () => {
expect(linearPrimeSieve(5)).toEqual([2, 3, 5]);
expect(linearPrimeSieve(10)).toEqual([2, 3, 5, 7]);
expect(linearPrimeSieve(100)).toEqual([
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
]);
});
});
35 changes: 35 additions & 0 deletions src/algorithms/math/linear-prime-sieve/linearPrimeSieve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @param {number} maxNumber
* @return {number[]}
*/
export default function linearPrimeSieve(maxNumber) {
const primes = [];
// leastPrimeFactor[i] gives us the least prime factor of 'i'
const leastPrimeFactor = new Array(maxNumber + 1).fill(0);

for (let i = 2; i <= maxNumber; i += 1) {
if (!leastPrimeFactor[i]) {
/* leastPrimeFactor[i] = 0 means 'i' itself is its least prime factor,
* i.e 'i' is prime
*/
leastPrimeFactor[i] = i;
primes.push(i);
}

/*
* start setting leastPrimeFactor[] for numbers 'x', where x = p * i, p is x's
* least prime factor and p <= leastPrimeFactor[i]. x = p*i, this representation will
* be unique for any number, therefore leastPrimeFactor[x] will be
* set only once.
*/

let j = 0;
while (j < primes.length) {
if ((primes[j] * i > maxNumber) || (primes[j] > leastPrimeFactor[i])) { break; }
leastPrimeFactor[primes[j] * i] = primes[j];
j += 1;
}
}

return primes;
}