mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-11-10 11:09:43 +08:00
Merge 7fd168d7d0
into ca3d16dcce
This commit is contained in:
commit
107e239366
44
src/algorithms/math/linear-prime-sieve/README.md
Normal file
44
src/algorithms/math/linear-prime-sieve/README.md
Normal file
@ -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).
|
@ -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
src/algorithms/math/linear-prime-sieve/linearPrimeSieve.js
Normal file
35
src/algorithms/math/linear-prime-sieve/linearPrimeSieve.js
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user