From de9ec2332b4620d0604acde32b1441113ea430dc Mon Sep 17 00:00:00 2001 From: Fahim Faisaal Date: Wed, 2 Mar 2022 07:16:53 +0600 Subject: [PATCH 1/6] feat: add negative power option --- Maths/Pow.js | 17 +++++++++++------ Maths/test/Pow.test.js | 14 +++++++++----- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Maths/Pow.js b/Maths/Pow.js index 555e652aa6..01da017d73 100644 --- a/Maths/Pow.js +++ b/Maths/Pow.js @@ -1,11 +1,16 @@ -// Returns the value of x to the power of y - -const pow = (x, y) => { +const powOn = (base, power) => { + if (power < 0) { + base = 1 / base + power = -power + } + let result = 1 - for (let i = 1; i <= y; i++) { - result *= x + + while (power--) { // Break the execution while the power will 0 + result *= base } + return result } -export { pow } +export { powOn } diff --git a/Maths/test/Pow.test.js b/Maths/test/Pow.test.js index f5760048eb..b9e2aa71a3 100644 --- a/Maths/test/Pow.test.js +++ b/Maths/test/Pow.test.js @@ -1,15 +1,19 @@ -import { pow } from '../Pow' +import { powOn } from '../Pow' -describe('Pow', () => { +describe('Testing PowOn', () => { it('should return 1 for numbers with exponent 0', () => { - expect(pow(2, 0)).toBe(1) + expect(powOn(2, 0)).toBe(1) + }) + + it('should return 0.5 for numbers with exponent -1', () => { + expect(powOn(2, -1)).toBe(0.5) }) it('should return 0 for numbers with base 0', () => { - expect(pow(0, 23)).toBe(0) + expect(powOn(0, 23)).toBe(0) }) it('should return the base to the exponent power', () => { - expect(pow(24, 4)).toBe(331776) + expect(powOn(24, 4)).toBe(331776) }) }) From b593735302b193ef022231b6c0f90b79b39bc87b Mon Sep 17 00:00:00 2001 From: Fahim Faisaal Date: Wed, 2 Mar 2022 07:17:51 +0600 Subject: [PATCH 2/6] docs: add js doc for powOn function --- Maths/Pow.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Maths/Pow.js b/Maths/Pow.js index 01da017d73..c6ab56cb70 100644 --- a/Maths/Pow.js +++ b/Maths/Pow.js @@ -1,3 +1,12 @@ +/** + * @function powOn + * @description - The powOn function is a power function with Linear O(n) complexity + * @param {number} base + * @param {number} power + * @returns {number} + * @example - powOn(2, 2) => 4 --> 2 * 2 + * @example - powOn(3, 3) => 27 --> 3 * 3 * + */ const powOn = (base, power) => { if (power < 0) { base = 1 / base From 37525fbf18ed92055e0bf5b5aeb3b8a1bc9bce69 Mon Sep 17 00:00:00 2001 From: Fahim Faisaal Date: Wed, 2 Mar 2022 07:33:56 +0600 Subject: [PATCH 3/6] feat: add PowFaster with faster algorithm, complexity O(logN) --- Maths/Pow.js | 49 ++++++++++++++++++++++++++++++++++++------ Maths/test/Pow.test.js | 34 +++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/Maths/Pow.js b/Maths/Pow.js index c6ab56cb70..f4daf131e1 100644 --- a/Maths/Pow.js +++ b/Maths/Pow.js @@ -1,13 +1,13 @@ /** - * @function powOn - * @description - The powOn function is a power function with Linear O(n) complexity + * @function powLinear + * @description - The powLinear function is a power function with Linear O(n) complexity * @param {number} base * @param {number} power * @returns {number} - * @example - powOn(2, 2) => 4 --> 2 * 2 - * @example - powOn(3, 3) => 27 --> 3 * 3 * + * @example - powLinear(2, 2) => 4 --> 2 * 2 + * @example - powLinear(3, 3) => 27 --> 3 * 3 */ -const powOn = (base, power) => { +const powLinear = (base, power) => { if (power < 0) { base = 1 / base power = -power @@ -22,4 +22,41 @@ const powOn = (base, power) => { return result } -export { powOn } +/** + * @function powFaster + * @description - The powFaster function is a power function with Linear O(n) complexity + * @param {number} base + * @param {number} power + * @returns {number} + * @example - powFaster(2, 2) => 4 --> 2 * 2 + * @example - powFaster(3, 3) => 27 --> 3 * 3 + */ +const powFaster = (base, power) => { + if (power < 2) { // explanation below - 1 + return base && ([1, base][power] || powFaster(1 / base, -power)) + } + + if (power & 1) { // if the existing power is odd + return base * powFaster(base * base, power >> 1) // explanation below - 2 + } + + return powFaster(base * base, power / 2) +} + +/** + * 1 - Magic of short circuit evaluation (&&, ||) + * if the base is 0 then it returns 0 cause 0 is falsy + * if the base is not 0 then it's must be truthy. after that, it will be executed the right portion of the && (AND) operator + * Now it checks the power by the help array index, is it 0 or 1. + * if the power is not 0 or 1 it's definitely less than 0, and a negative number is not a valid index number so it returns "undefined" + * if the expression is undefined mean -> falsy, the || (OR) operator evaluates the right portion that is a recursive function. + */ + +/** + * 2 - Play with right shift bitwise operator (>>) + * right shift with any odd numbers it returns the floor number instead of float. + * E.g. if the number is 5, after right shifting with 1 it's will give us 2, not 2.5 + * cause the right shift formula is --> x >> y = |x| / 2^y + */ + +export { powLinear, powFaster } diff --git a/Maths/test/Pow.test.js b/Maths/test/Pow.test.js index b9e2aa71a3..9ffb64e52d 100644 --- a/Maths/test/Pow.test.js +++ b/Maths/test/Pow.test.js @@ -1,19 +1,41 @@ -import { powOn } from '../Pow' +import { powLinear, powFaster } from '../Pow' -describe('Testing PowOn', () => { +describe('Testing powLinear function', () => { it('should return 1 for numbers with exponent 0', () => { - expect(powOn(2, 0)).toBe(1) + expect(powLinear(2, 0)).toBe(1) }) it('should return 0.5 for numbers with exponent -1', () => { - expect(powOn(2, -1)).toBe(0.5) + expect(powLinear(2, -1)).toBe(0.5) }) it('should return 0 for numbers with base 0', () => { - expect(powOn(0, 23)).toBe(0) + expect(powLinear(0, 23)).toBe(0) }) it('should return the base to the exponent power', () => { - expect(powOn(24, 4)).toBe(331776) + expect(powLinear(24, 4)).toBe(331776) + }) +}) + +describe('Testing powFaster function', () => { + it('should return 1 for numbers with exponent 0', () => { + expect(powFaster(2, 0)).toBe(1) + }) + + it('should return 0.5 for numbers with exponent -1', () => { + expect(powFaster(2, -1)).toBe(0.5) + }) + + it('should return 0 for numbers with base 0', () => { + expect(powFaster(0, 23)).toBe(0) + }) + + it('should return the base to the exponent power', () => { + expect(powFaster(24, 4)).toBe(331776) + }) + + it('should return the result in O(lonN) complexity', () => { + expect(powFaster(2, 64)).toBe(18446744073709552000) // execution time Math.log2(64) -> 6 }) }) From 40db24eb268c652109101bb538d216f4968c5b72 Mon Sep 17 00:00:00 2001 From: Fahim Faisaal Date: Wed, 2 Mar 2022 07:56:00 +0600 Subject: [PATCH 4/6] chore: rename to exponent --- Maths/Pow.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Maths/Pow.js b/Maths/Pow.js index f4daf131e1..1cd85744b4 100644 --- a/Maths/Pow.js +++ b/Maths/Pow.js @@ -2,20 +2,20 @@ * @function powLinear * @description - The powLinear function is a power function with Linear O(n) complexity * @param {number} base - * @param {number} power + * @param {number} exponent * @returns {number} * @example - powLinear(2, 2) => 4 --> 2 * 2 * @example - powLinear(3, 3) => 27 --> 3 * 3 */ -const powLinear = (base, power) => { - if (power < 0) { +const powLinear = (base, exponent) => { + if (exponent < 0) { base = 1 / base - power = -power + exponent = -exponent } let result = 1 - while (power--) { // Break the execution while the power will 0 + while (exponent--) { // Break the execution while the exponent will 0 result *= base } @@ -26,29 +26,29 @@ const powLinear = (base, power) => { * @function powFaster * @description - The powFaster function is a power function with Linear O(n) complexity * @param {number} base - * @param {number} power + * @param {number} exponent * @returns {number} * @example - powFaster(2, 2) => 4 --> 2 * 2 * @example - powFaster(3, 3) => 27 --> 3 * 3 */ -const powFaster = (base, power) => { - if (power < 2) { // explanation below - 1 - return base && ([1, base][power] || powFaster(1 / base, -power)) +const powFaster = (base, exponent) => { + if (exponent < 2) { // explanation below - 1 + return base && ([1, base][exponent] || powFaster(1 / base, -exponent)) } - if (power & 1) { // if the existing power is odd - return base * powFaster(base * base, power >> 1) // explanation below - 2 + if (exponent & 1) { // if the existing exponent is odd + return base * powFaster(base * base, exponent >> 1) // explanation below - 2 } - return powFaster(base * base, power / 2) + return powFaster(base * base, exponent / 2) } /** * 1 - Magic of short circuit evaluation (&&, ||) * if the base is 0 then it returns 0 cause 0 is falsy * if the base is not 0 then it's must be truthy. after that, it will be executed the right portion of the && (AND) operator - * Now it checks the power by the help array index, is it 0 or 1. - * if the power is not 0 or 1 it's definitely less than 0, and a negative number is not a valid index number so it returns "undefined" + * Now it checks the exponent by the help array index, is it 0 or 1. + * if the exponent is not 0 or 1 it's definitely less than 0, and a negative number is not a valid index number so it returns "undefined" * if the expression is undefined mean -> falsy, the || (OR) operator evaluates the right portion that is a recursive function. */ From d912deeecbab1cce9e34d4a8b0e44c3587c7f049 Mon Sep 17 00:00:00 2001 From: Fahim Faisaal Date: Wed, 2 Mar 2022 07:57:24 +0600 Subject: [PATCH 5/6] chore: rename fixed --- Maths/Pow.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maths/Pow.js b/Maths/Pow.js index 1cd85744b4..fa8248f173 100644 --- a/Maths/Pow.js +++ b/Maths/Pow.js @@ -24,7 +24,7 @@ const powLinear = (base, exponent) => { /** * @function powFaster - * @description - The powFaster function is a power function with Linear O(n) complexity + * @description - The powFaster function is a power function with O(logN) complexity * @param {number} base * @param {number} exponent * @returns {number} From d3bbf5bf177ef6ffbd5c3398dc7aed3937fd29a3 Mon Sep 17 00:00:00 2001 From: Fahim Faisaal Date: Wed, 2 Mar 2022 08:05:28 +0600 Subject: [PATCH 6/6] style: formated with standard --- Maths/Pow.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Maths/Pow.js b/Maths/Pow.js index fa8248f173..e75ec412b5 100644 --- a/Maths/Pow.js +++ b/Maths/Pow.js @@ -1,8 +1,8 @@ /** * @function powLinear * @description - The powLinear function is a power function with Linear O(n) complexity - * @param {number} base - * @param {number} exponent + * @param {number} base + * @param {number} exponent * @returns {number} * @example - powLinear(2, 2) => 4 --> 2 * 2 * @example - powLinear(3, 3) => 27 --> 3 * 3 @@ -12,10 +12,10 @@ const powLinear = (base, exponent) => { base = 1 / base exponent = -exponent } - + let result = 1 - while (exponent--) { // Break the execution while the exponent will 0 + while (exponent--) { // Break the execution while the exponent will 0 result *= base } @@ -25,8 +25,8 @@ const powLinear = (base, exponent) => { /** * @function powFaster * @description - The powFaster function is a power function with O(logN) complexity - * @param {number} base - * @param {number} exponent + * @param {number} base + * @param {number} exponent * @returns {number} * @example - powFaster(2, 2) => 4 --> 2 * 2 * @example - powFaster(3, 3) => 27 --> 3 * 3