diff --git a/README.md b/README.md index 4ec02b5f..7a839316 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ * [Fibonacci Number](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/fibonacci) * [Cartesian Product](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/cartesian-product) * [Power Set](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/power-set) + * [Primality Tests](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/primality-tests) * Collatz Conjecture algorithm * Extended Euclidean algorithm * Euclidean algorithm to calculate the Greatest Common Divisor (GCD) @@ -39,7 +40,6 @@ * Greatest Difference * Least Common Multiple * Newton's square - * Primality Test * Shannon Entropy * **String** * [String Permutations](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/string/permutations) diff --git a/src/algorithms/math/primality-tests/README.md b/src/algorithms/math/primality-tests/README.md new file mode 100644 index 00000000..fd5af656 --- /dev/null +++ b/src/algorithms/math/primality-tests/README.md @@ -0,0 +1,14 @@ +# Primality Test + +A primality test is an algorithm for determining whether an input +number is prime. Among other fields of mathematics, it is used +for cryptography. Unlike integer factorization, primality tests +do not generally give prime factors, only stating whether the +input number is prime or not. Factorization is thought to be +a computationally difficult problem, whereas primality testing +is comparatively easy (its running time is polynomial in the +size of the input). + +## References + +[Wikipedia](https://en.wikipedia.org/wiki/Primality_test) diff --git a/src/algorithms/math/primality-tests/__test__/primalityTest.js b/src/algorithms/math/primality-tests/__test__/primalityTest.js new file mode 100644 index 00000000..96edb3c6 --- /dev/null +++ b/src/algorithms/math/primality-tests/__test__/primalityTest.js @@ -0,0 +1,22 @@ +/** + * @param {function(n: number)} testFunction + */ +export default function primalityTest(testFunction) { + expect(testFunction(1)).toBeTruthy(); + expect(testFunction(2)).toBeTruthy(); + expect(testFunction(3)).toBeTruthy(); + expect(testFunction(5)).toBeTruthy(); + expect(testFunction(11)).toBeTruthy(); + expect(testFunction(191)).toBeTruthy(); + expect(testFunction(191)).toBeTruthy(); + expect(testFunction(199)).toBeTruthy(); + + expect(testFunction(-1)).toBeFalsy(); + expect(testFunction(0)).toBeFalsy(); + expect(testFunction(4)).toBeFalsy(); + expect(testFunction(6)).toBeFalsy(); + expect(testFunction(12)).toBeFalsy(); + expect(testFunction(192)).toBeFalsy(); + expect(testFunction(200)).toBeFalsy(); + expect(testFunction(400)).toBeFalsy(); +} diff --git a/src/algorithms/math/primality-tests/__test__/trialDivision.test.js b/src/algorithms/math/primality-tests/__test__/trialDivision.test.js new file mode 100644 index 00000000..c9c8ea1e --- /dev/null +++ b/src/algorithms/math/primality-tests/__test__/trialDivision.test.js @@ -0,0 +1,8 @@ +import trialDivision from '../trialDivision'; +import primalityTest from './primalityTest'; + +describe('trialDivision', () => { + it('should detect prime numbers', () => { + primalityTest(trialDivision); + }); +}); diff --git a/src/algorithms/math/primality-tests/trialDivision.js b/src/algorithms/math/primality-tests/trialDivision.js new file mode 100644 index 00000000..eb3272e2 --- /dev/null +++ b/src/algorithms/math/primality-tests/trialDivision.js @@ -0,0 +1,28 @@ +/** + * @param {number} number + * @return {boolean} + */ +export default function trialDivision(number) { + if (number <= 0) { + // If number is less then one then it isn't prime by definition. + return false; + } else if (number <= 3) { + // All numbers from 1 to 3 are prime. + return true; + } + + // If the number is not divided by 2 then we may eliminate all further even dividers. + if (number % 2 === 0) { + return false; + } + + // If there is no dividers up to square root of n then there is no higher dividers as well. + const dividerLimit = Math.sqrt(number); + for (let divider = 3; divider < dividerLimit; divider += 2) { + if (number % divider === 0) { + return false; + } + } + + return true; +}