Skip to content

Commit 042f52c

Browse files
feat(maths): adds prime sieve and generator (TheAlgorithms#144)
* Update DIRECTORY.md * feat(maths): adds prime sieve and generator * Update DIRECTORY.md --------- Co-authored-by: autoprettier <[email protected]>
1 parent e8a850c commit 042f52c

File tree

5 files changed

+215
-52
lines changed

5 files changed

+215
-52
lines changed

DIRECTORY.md

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,79 @@
33
* [Xor Cipher](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/ciphers/xor_cipher.ts)
44

55
## Data Structures
6-
* [Array Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/array_queue.ts)
7-
* [Linked Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/linked_queue.ts)
8-
* [Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue.ts)
9-
* [Stack](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/stack.ts)
10-
* [Stack Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/stack_queue.ts)
6+
* Disjoint Set
7+
* [Disjoint Set](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/disjoint_set/disjoint_set.ts)
8+
* Test
9+
* [Disjoint Set.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/disjoint_set/test/disjoint_set.test.ts)
10+
* Heap
11+
* [Heap](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/heap/heap.ts)
12+
* Test
13+
* [Max Heap.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/heap/test/max_heap.test.ts)
14+
* [Min Heap.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/heap/test/min_heap.test.ts)
15+
* List
16+
* [Doubly Linked List](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/list/doubly_linked_list.ts)
17+
* [Linked List](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/list/linked_list.ts)
18+
* [Singly Linked List](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/list/singly_linked_list.ts)
19+
* Test
20+
* [Doubly Linked List.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/list/test/doubly_linked_list.test.ts)
21+
* [Linked List](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/list/test/linked_list.ts)
22+
* [Singly Linked List.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/list/test/singly_linked_list.test.ts)
23+
* Map
24+
* [Hash Map](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/map/hash_map.ts)
25+
* [Map](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/map/map.ts)
26+
* Test
27+
* [Hash Map.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/map/test/hash_map.test.ts)
28+
* Queue
29+
* [Array Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/array_queue.ts)
30+
* [Circular Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/circular_queue.ts)
31+
* [Linked Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/linked_queue.ts)
32+
* [Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/queue.ts)
33+
* [Stack Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/stack_queue.ts)
34+
* Test
35+
* [Array Queue.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/test/array_queue.test.ts)
36+
* [Circular Queue.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/test/circular_queue.test.ts)
37+
* [Linked Queue.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/test/linked_queue.test.ts)
38+
* [Queue](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/test/queue.ts)
39+
* [Stack Queue.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/queue/test/stack_queue.test.ts)
40+
* Set
41+
* [Hash Map Set](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/set/hash_map_set.ts)
42+
* [Map Set](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/set/map_set.ts)
43+
* [Set](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/set/set.ts)
44+
* Stack
45+
* [Linked List Stack](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/stack/linked_list_stack.ts)
46+
* [Stack](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/stack/stack.ts)
47+
* Test
48+
* [Linked List Stack.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/stack/test/linked_list_stack.test.ts)
49+
* [Stack.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/stack/test/stack.test.ts)
50+
* Tree
51+
* [Binary Search Tree](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/tree/binary_search_tree.ts)
52+
* Test
53+
* [Binary Search Tree.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/data_structures/tree/test/binary_search_tree.test.ts)
1154

1255
## Dynamic Programming
1356
* [Knapsack](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/knapsack.ts)
1457

58+
## Graph
59+
* [Bellman Ford](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/bellman_ford.ts)
60+
* [Dijkstra](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/dijkstra.ts)
61+
* [Kruskal](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/kruskal.ts)
62+
* Test
63+
* [Bellman Ford.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/bellman_ford.test.ts)
64+
* [Dijkstra.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/dijkstra.test.ts)
65+
* [Kruskal.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/test/kruskal.test.ts)
66+
1567
## Maths
1668
* [Absolute Value](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/absolute_value.ts)
1769
* [Aliquot Sum](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/aliquot_sum.ts)
1870
* [Armstrong Number](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/armstrong_number.ts)
1971
* [Binary Convert](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/binary_convert.ts)
72+
* [Binomial Coefficient](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/binomial_coefficient.ts)
2073
* [Calculate Mean](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/calculate_mean.ts)
74+
* [Calculate Median](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/calculate_median.ts)
2175
* [Degrees To Radians](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/degrees_to_radians.ts)
2276
* [Digit Sum](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/digit_sum.ts)
2377
* [Factorial](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/factorial.ts)
78+
* [Factors](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/factors.ts)
2479
* [Fibonacci](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/fibonacci.ts)
2580
* [Find Min](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/find_min.ts)
2681
* [Greatest Common Factor](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/greatest_common_factor.ts)
@@ -31,8 +86,13 @@
3186
* [Is Odd](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_odd.ts)
3287
* [Is Palindrome](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_palindrome.ts)
3388
* [Is Square Free](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_square_free.ts)
89+
* [Juggler Sequence](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/juggler_sequence.ts)
3490
* [Lowest Common Multiple](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/lowest_common_multiple.ts)
91+
* [Number Of Digits](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/number_of_digits.ts)
92+
* [Pascals Triangle](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/pascals_triangle.ts)
93+
* [Perfect Cube](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_cube.ts)
3594
* [Perfect Square](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_square.ts)
95+
* [Primes](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/primes.ts)
3696
* [Pronic Number](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/pronic_number.ts)
3797
* [Radians To Degrees](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/radians_to_degrees.ts)
3898
* Series
@@ -41,6 +101,7 @@
41101
* [Hexagonal Numbers.Test](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/series/test/hexagonal_numbers.test.ts)
42102
* [Sieve Of Eratosthenes](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/sieve_of_eratosthenes.ts)
43103
* [Signum](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/signum.ts)
104+
* [Zellers Congruence](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/zellers_congruence.ts)
44105

45106
## Other
46107
* [Parse Nested Brackets](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/other/parse_nested_brackets.ts)
@@ -58,4 +119,7 @@
58119
* [Gnome Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/gnome_sort.ts)
59120
* [Insertion Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/insertion_sort.ts)
60121
* [Merge Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/merge_sort.ts)
122+
* [Quick Select](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/quick_select.ts)
61123
* [Quick Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/quick_sort.ts)
124+
* [Selection Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/selection_sort.ts)
125+
* [Shell Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/shell_sort.ts)

maths/is_prime.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

maths/primes.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* Implementation of the Sieve of Eratosthenes algorithm.
3+
*
4+
* @param limit An integer _n_ > 1
5+
* @returns All prime numbers from 2 through {@link limit}
6+
*
7+
* @see https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
8+
*/
9+
export function sieveOfEratosthenes(limit: number): number[] {
10+
if (!Number.isInteger(limit) || limit <= 1) {
11+
throw new Error("limit should be an integer greater than 1");
12+
}
13+
14+
const maybePrime: boolean[] = new Array(limit + 1).fill(true);
15+
for (let i = 2; i * i <= limit; i++) {
16+
if (!maybePrime[i]) continue;
17+
for (let j = i * i; j <= limit; j += i) {
18+
maybePrime[j] = false;
19+
}
20+
}
21+
22+
const primes: number[] = [];
23+
for (let i = 2; i < maybePrime.length; i++) {
24+
if (maybePrime[i]) {
25+
primes.push(i);
26+
}
27+
}
28+
29+
return primes;
30+
}
31+
32+
/**
33+
* Generator that yields primes.
34+
*
35+
* Inspired by https://gist.github.com/e-nikolov/cd94db0de2a6b70da144124ae93a6458
36+
*/
37+
export function* primeGenerator() {
38+
type NumberGen = Generator<number, void, any>;
39+
40+
function* filter(input: NumberGen, prime: number): NumberGen {
41+
while (true) {
42+
const {done, value} = input.next();
43+
if (done) break;
44+
if (value % prime !== 0) yield value;
45+
}
46+
}
47+
48+
let chain: NumberGen = (function* () {
49+
let i = 2;
50+
while (true) yield i++;
51+
})();
52+
53+
while (true) {
54+
const {done, value} = chain.next();
55+
if (done) break;
56+
yield value;
57+
chain = filter(chain, value);
58+
}
59+
}
60+
61+
/**
62+
* @function isPrime
63+
* @description Determine if given number is prime.
64+
* @param {number} num - A natural number.
65+
* @return {boolean} - Whether the given number is prime.
66+
* @see https://en.wikipedia.org/wiki/Prime_number
67+
* @example isPrime(2) = false
68+
* @example isPrime(3) = true
69+
*/
70+
export const isPrime = (num: number): boolean => {
71+
// raise corresponding errors upon invalid inputs
72+
if (num <= 0 || !Number.isInteger(num)) {
73+
throw new Error("only natural numbers are supported");
74+
}
75+
76+
// handle input being 1
77+
if (num === 1) return false;
78+
79+
// iterate from 2 to the square root of num to find a factor
80+
// return false upon finding a factor
81+
for (let i = 2; i <= Math.sqrt(num); i++) {
82+
if (num % i === 0) return false;
83+
}
84+
85+
// if the entire loop runs without finding a factor, return true
86+
return true;
87+
};

maths/test/is_prime.test.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

maths/test/primes.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {isPrime, primeGenerator, sieveOfEratosthenes} from "../primes";
2+
3+
4+
describe(sieveOfEratosthenes, () => {
5+
test.each([-1, 0, 1, 2.123, 1337.80085])(
6+
"should throw an error when given an invalid limit=%d",
7+
(invalidLimit) => {
8+
expect(() => sieveOfEratosthenes(invalidLimit)).toThrow();
9+
}
10+
);
11+
test.each([
12+
[2, [2]],
13+
[3, [2, 3]],
14+
[4, [2, 3]],
15+
[5, [2, 3, 5]],
16+
[6, [2, 3, 5]],
17+
[7, [2, 3, 5, 7]],
18+
[8, [2, 3, 5, 7]],
19+
[9, [2, 3, 5, 7]],
20+
])(
21+
"should return the expected list of primes for limit=%i",
22+
(limit, expected) => {
23+
expect(sieveOfEratosthenes(limit)).toEqual(expected);
24+
}
25+
);
26+
});
27+
28+
describe(primeGenerator, () => {
29+
it("should generate prime numbers", () => {
30+
const primeGen = primeGenerator();
31+
for (let i = 0; i < 100; i++) {
32+
const prime = primeGen.next().value;
33+
34+
if (prime === undefined) {
35+
throw new Error("prime generator returned undefined");
36+
}
37+
38+
expect(isPrime(prime)).toBe(true);
39+
}
40+
});
41+
});
42+
43+
describe("IsPrime", () => {
44+
test.each([[1, false], [2, true], [3, true], [3 * 3, false], [13, true], [24, false]])(
45+
"correct output for %i",
46+
(nums, expected) => {
47+
expect(isPrime(nums)).toBe(expected);
48+
},
49+
);
50+
51+
test.each([-890, -5.56, -7, 0.73, 4.2, NaN, -Infinity, Infinity])(
52+
"should throw an error for non natural number %d",
53+
(num) => {
54+
expect(() => isPrime(num)).toThrowError(
55+
"only natural numbers are supported",
56+
);
57+
},
58+
);
59+
});

0 commit comments

Comments
 (0)