Code styling fixes for Sieve of Eratosthenes.

This commit is contained in:
Oleksii Trekhleb 2018-06-03 09:34:48 +03:00
parent 943f83492a
commit 91d4714d19
4 changed files with 31 additions and 19 deletions

View File

@ -49,6 +49,7 @@ a set of rules that precisely define a sequence of operations.
* [Euclidean Algorithm](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/euclidean-algorithm) - calculate the Greatest Common Divisor (GCD) * [Euclidean Algorithm](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/euclidean-algorithm) - calculate the Greatest Common Divisor (GCD)
* [Least Common Multiple](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/least-common-multiple) (LCM) * [Least Common Multiple](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/least-common-multiple) (LCM)
* [Integer Partition](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/integer-partition) * [Integer Partition](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/integer-partition)
* [Sieve of Eratosthenes](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/sieve-of-eratosthenes) - finding all prime numbers up to any given limit
* **Sets** * **Sets**
* [Cartesian Product](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sets/cartesian-product) - product of multiple sets * [Cartesian Product](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sets/cartesian-product) - product of multiple sets
* [Power Set](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sets/power-set) - all subsets of a set * [Power Set](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sets/power-set) - all subsets of a set

View File

@ -6,15 +6,18 @@ It is attributed to Eratosthenes of Cyrene, an ancient Greek mathematician.
## How it works ## How it works
1. Create a boolean array of `n+1` positions (to represent the numbers `0` through `n`) 1. Create a boolean array of `n + 1` positions (to represent the numbers `0` through `n`)
2. Set positions `0` and `1` to `false`, and the rest to `true` 2. Set positions `0` and `1` to `false`, and the rest to `true`
3. Start at position `p = 2` (the first prime number) 3. Start at position `p = 2` (the first prime number)
4. Mark as `false` all the multiples of `p` (that is, positions `2*p`, `3*p`, `4*p`... until you reach the end of the array) 4. Mark as `false` all the multiples of `p` (that is, positions `2 * p`, `3 * p`, `4 * p`... until you reach the end of the array)
5. Find the first position greater than `p` that is `true` in the array. If there is no such position, stop. Otherwise, let `p` equal this new number (which is the next prime), and repeat from step 4 5. Find the first position greater than `p` that is `true` in the array. If there is no such position, stop. Otherwise, let `p` equal this new number (which is the next prime), and repeat from step 4
When the algorithm terminates, the numbers remaining `true` in the array are all the primes below `n`. When the algorithm terminates, the numbers remaining `true` in the array are all
the primes below `n`.
An improvement of this algorithm is, in step 4, start marking multiples of `p` from `p*p`, and not from `2*p`. The reason why this works is because, at that point, smaller multiples of `p` will have already been marked `false`. An improvement of this algorithm is, in step 4, start marking multiples
of `p` from `p * p`, and not from `2 * p`. The reason why this works is because,
at that point, smaller multiples of `p` will have already been marked `false`.
## Example ## Example
@ -26,4 +29,4 @@ The algorithm has a complexity of `O(n log(log n))`.
## References ## References
[Wikipedia](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) - [Wikipedia](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)

View File

@ -1,6 +1,6 @@
import sieveOfEratosthenes from '../sieveOfEratosthenes'; import sieveOfEratosthenes from '../sieveOfEratosthenes';
describe('factorial', () => { describe('sieveOfEratosthenes', () => {
it('should find all primes less than or equal to n', () => { it('should find all primes less than or equal to n', () => {
expect(sieveOfEratosthenes(5)).toEqual([2, 3, 5]); expect(sieveOfEratosthenes(5)).toEqual([2, 3, 5]);
expect(sieveOfEratosthenes(10)).toEqual([2, 3, 5, 7]); expect(sieveOfEratosthenes(10)).toEqual([2, 3, 5, 7]);

View File

@ -1,25 +1,33 @@
/** /**
* @param {number} n * @param {number} maxNumber
* @return {number[]} * @return {number[]}
*/ */
export default function sieveOfEratosthenes(n) { export default function sieveOfEratosthenes(maxNumber) {
const isPrime = new Array(n + 1).fill(true); const isPrime = new Array(maxNumber + 1).fill(true);
isPrime[0] = false; isPrime[0] = false;
isPrime[1] = false; isPrime[1] = false;
const primes = []; const primes = [];
for (let i = 2; i <= n; i += 1) { for (let number = 2; number <= maxNumber; number += 1) {
if (isPrime[i] === true) { if (isPrime[number] === true) {
primes.push(i); primes.push(number);
// Warning: When working with really big numbers, the following line may cause overflow /*
// In that case, it can be changed to: * Optimisation.
// let j = 2 * i; * Start marking multiples of `p` from `p * p`, and not from `2 * p`.
let j = i * i; * The reason why this works is because, at that point, smaller multiples
* of `p` will have already been marked `false`.
*
* Warning: When working with really big numbers, the following line may cause overflow
* In that case, it can be changed to:
* let nextNumber = 2 * number;
*/
let nextNumber = number * number;
while (j <= n) { while (nextNumber <= maxNumber) {
isPrime[j] = false; isPrime[nextNumber] = false;
j += i; nextNumber += number;
} }
} }
} }