From 8116aa7cfb69e77b36eaf1441e5f96c8051cf863 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Tue, 4 Sep 2018 17:35:48 +0300 Subject: [PATCH] Refactor fast powering algorithm. --- README.md | 2 ++ .../__test__/computePower.test.js | 16 ------------- .../README.md | 6 ++++- .../__test__/fastPowering.test.js | 23 +++++++++++++++++++ .../fastPowering.js} | 16 ++++++------- 5 files changed, 38 insertions(+), 25 deletions(-) delete mode 100644 src/algorithms/math/compute-power/__test__/computePower.test.js rename src/algorithms/math/{compute-power => fast-powering}/README.md (95%) create mode 100644 src/algorithms/math/fast-powering/__test__/fastPowering.test.js rename src/algorithms/math/{compute-power/power.js => fast-powering/fastPowering.js} (54%) diff --git a/README.md b/README.md index 915b3fb3..527f30dc 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ a set of rules that precisely define a sequence of operations. * `B` [Pascal's Triangle](src/algorithms/math/pascal-triangle) * `B` [Complex Number](src/algorithms/math/complex-number) - complex numbers and basic operations with them * `B` [Radian & Degree](src/algorithms/math/radian) - radians to degree and backwards conversion + * `B` [Fast Powering](src/algorithms/math/fast-powering) * `A` [Integer Partition](src/algorithms/math/integer-partition) * `A` [Liu Hui π Algorithm](src/algorithms/math/liu-hui) - approximate π calculations based on N-gons * `A` [Discrete Fourier Transform](src/algorithms/math/fourier-transform) - decompose a function of time (a signal) into the frequencies that make it up @@ -163,6 +164,7 @@ algorithm is an abstraction higher than a computer program. * `B` [Tree Depth-First Search](src/algorithms/tree/depth-first-search) (DFS) * `B` [Graph Depth-First Search](src/algorithms/graph/depth-first-search) (DFS) * `B` [Jump Game](src/algorithms/uncategorized/jump-game) + * `B` [Fast Powering](src/algorithms/math/fast-powering) * `A` [Permutations](src/algorithms/sets/permutations) (with and without repetitions) * `A` [Combinations](src/algorithms/sets/combinations) (with and without repetitions) * **Dynamic Programming** - build up a solution using previously found sub-solutions diff --git a/src/algorithms/math/compute-power/__test__/computePower.test.js b/src/algorithms/math/compute-power/__test__/computePower.test.js deleted file mode 100644 index 944d562b..00000000 --- a/src/algorithms/math/compute-power/__test__/computePower.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import computePower from '../power'; - -describe('computePower', () => { - it('should compute Power', () => { - expect(computePower(1, 1)).toBe(1); - expect(computePower(2, 0)).toBe(1); - expect(computePower(3, 4)).toBe(81); - expect(computePower(190, 2)).toBe(36100); - expect(computePower(16, 16)).toBe(18446744073709552000); - expect(computePower(100, 9)).toBe(1000000000000000000); - expect(computePower(9, 16)).toBe(1853020188851841); - expect(computePower(11, 5)).toBe(161051); - expect(computePower(13, 11)).toBe(1792160394037); - expect(computePower(7, 21)).toBe(558545864083284000); - }); -}); diff --git a/src/algorithms/math/compute-power/README.md b/src/algorithms/math/fast-powering/README.md similarity index 95% rename from src/algorithms/math/compute-power/README.md rename to src/algorithms/math/fast-powering/README.md index a0219c06..d8364888 100644 --- a/src/algorithms/math/compute-power/README.md +++ b/src/algorithms/math/fast-powering/README.md @@ -1,4 +1,4 @@ -# Power(a,b) +# Fast Powering Algorithm This computes power of (a,b) eg: power(2,3) = 8 @@ -33,3 +33,7 @@ power(2,5) = 2 * power(2,2) * power(2,2) = 2 * 4 * 4 = 32 Complexity relation: T(n) = T(n/2) + 1 Time complexity of the algorithm: O(logn) + +## References + + diff --git a/src/algorithms/math/fast-powering/__test__/fastPowering.test.js b/src/algorithms/math/fast-powering/__test__/fastPowering.test.js new file mode 100644 index 00000000..0a5da756 --- /dev/null +++ b/src/algorithms/math/fast-powering/__test__/fastPowering.test.js @@ -0,0 +1,23 @@ +import fastPowering from '../fastPowering'; + +describe('fastPowering', () => { + it('should compute power in log(n) time', () => { + expect(fastPowering(1, 1)).toBe(1); + expect(fastPowering(2, 0)).toBe(1); + expect(fastPowering(2, 2)).toBe(4); + expect(fastPowering(2, 3)).toBe(8); + expect(fastPowering(2, 4)).toBe(16); + expect(fastPowering(2, 5)).toBe(32); + expect(fastPowering(2, 6)).toBe(64); + expect(fastPowering(2, 7)).toBe(128); + expect(fastPowering(2, 8)).toBe(256); + expect(fastPowering(3, 4)).toBe(81); + expect(fastPowering(190, 2)).toBe(36100); + expect(fastPowering(11, 5)).toBe(161051); + expect(fastPowering(13, 11)).toBe(1792160394037); + expect(fastPowering(9, 16)).toBe(1853020188851841); + expect(fastPowering(16, 16)).toBe(18446744073709552000); + expect(fastPowering(7, 21)).toBe(558545864083284000); + expect(fastPowering(100, 9)).toBe(1000000000000000000); + }); +}); diff --git a/src/algorithms/math/compute-power/power.js b/src/algorithms/math/fast-powering/fastPowering.js similarity index 54% rename from src/algorithms/math/compute-power/power.js rename to src/algorithms/math/fast-powering/fastPowering.js index 2fc3ee68..6841eb03 100644 --- a/src/algorithms/math/compute-power/power.js +++ b/src/algorithms/math/fast-powering/fastPowering.js @@ -1,11 +1,11 @@ /** - * @param {number1} number - * @param {number2} number - * @return {number1^number2} + * Recursive implementation to compute power. + * + * @param {number} number1 + * @param {number} number2 + * @return {number} */ - -// recursive implementation to compute power -export default function computePower(number1, number2) { +export default function fastPowering(number1, number2) { let val = 0; let res = 0; if (number2 === 0) { // if number2 is 0 @@ -13,10 +13,10 @@ export default function computePower(number1, number2) { } else if (number2 === 1) { // if number2 is 1 return number 1 as it is val = number1; } else if (number2 % 2 === 0) { // if number2 is even - res = computePower(number1, number2 / 2); + res = fastPowering(number1, number2 / 2); val = res * res; } else { // if number2 is odd - res = computePower(number1, Math.floor(number2 / 2)); + res = fastPowering(number1, Math.floor(number2 / 2)); val = res * res * number1; } return val;