From a5f3c3f3f01fd18815a76dca1097e9fbaf934e1e Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Thu, 5 Oct 2023 07:26:01 +0600 Subject: [PATCH 01/11] Create Fraction.js --- Maths/Fraction.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Maths/Fraction.js diff --git a/Maths/Fraction.js b/Maths/Fraction.js new file mode 100644 index 0000000000..766b944fe7 --- /dev/null +++ b/Maths/Fraction.js @@ -0,0 +1,66 @@ +/** + * @function fraction + * @description This function returns the fraction of a float type number. + * @param {number} num - a float type number is expected, but an integer will also work. + * @param {number} accuracy - the accuracy of the fraction, the default is 6. + * @return {Array} - an array containing the numerator and denominator of the fraction. + * @see https://en.wikipedia.org/wiki/Repeating_decimal and @see https://en.wikipedia.org/wiki/Decimal#Decimal_fractions + * @example fraction(0.5) // [1, 2] + * @example fraction(0.3333333333333333) // [1, 3] + * @example fraction(0.25) // [1, 4] + * @example fraction(5.56) // [139, 25] + * @example fraction(0.33) // [33, 100] + */ +function fraction(number, accuracy = 6) { + let inp = typeof number === "number" ? number : false; + let acc = typeof accuracy === "number" ? accuracy : false; + if (inp !== false && acc !== false) { + if (Number.isInteger(inp)) { + return [inp, 1]; + } else { + inp = inp.toString(); + let len; + let reg = inp.match(/(\d+?)\1+$/); + if (reg && reg[0].length > acc) { + let pos = inp.split("."); + inp = inp.replace(reg[0], reg[1]); + let rec = pos[0] + pos[1].replace(reg[0], ""); + inp = Number(rec + reg[1]) - Number(rec); + len = Number( + "9".repeat(reg[1].length) + "0".repeat(rec.length - pos[0].length) + ); + } else { + inp = inp.replace(".", ""); + len = 10 ** (inp.length - 1); + inp = Number(inp); + } + let d = true; + while (d) { + if (inp % 5 == 0 && len % 5 == 0) { + inp /= 5; + len /= 5; + } else if (inp % 2 == 0 && len % 2 == 0) { + inp /= 2; + len /= 2; + } else if (inp % 3 == 0 && len % 3 == 0) { + inp /= 3; + len /= 3; + } else if (inp % 7 == 0 && len % 7 == 0) { + inp /= 7; + len /= 7; + } else { + d = false; + } + } + return [inp, len]; + } + } else { + if (inp === false) { + throw new TypeError("Invalid number"); + } else { + throw new TypeError("Invalid accuracy"); + } + } +} + +export { fraction }; From e240332a9756834355f374bcb5255d783222fb25 Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Thu, 5 Oct 2023 07:26:46 +0600 Subject: [PATCH 02/11] Create Fraction.test.js --- Maths/test/Fraction.test.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Maths/test/Fraction.test.js diff --git a/Maths/test/Fraction.test.js b/Maths/test/Fraction.test.js new file mode 100644 index 0000000000..05547ea426 --- /dev/null +++ b/Maths/test/Fraction.test.js @@ -0,0 +1,28 @@ +import { fraction } from './../Fraction.js'; + +describe('Fraction', () => { + it('should return [1, 2] for 0.5', () => { + expect(fraction(0.5)).toEqual([1, 2]); + }); + it('should return [1, 3] for 0.3333333333333333', () => { + expect(fraction(0.3333333333333333)).toEqual([1, 3]); + }); + it('should return [1, 4] for 0.25', () => { + expect(fraction(0.25)).toEqual([1, 4]); + }); + it('should return [139, 25] for 5.56', () => { + expect(fraction(5.56)).toEqual([139, 25]); + }); + it('should return [33, 100] for 0.33', () => { + expect(fraction(0.33)).toEqual([33, 100]); + }); + it('should return [5, 1] for 1', () => { + expect(fraction(5)).toEqual([5, 1]); + }); + it('should return [3333, 1000] for 3.333', () => { + expect(fraction(3.33)).toEqual([333, 100]); + }); + it('should return [1, 3] for 0.3333', () => { + expect(fraction(0.3333, 3)).toEqual([1, 3]); + }); +}); From 6dbea14dc1f13fe09694dcee6b8c9f0664fe6c9e Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Thu, 5 Oct 2023 07:27:35 +0600 Subject: [PATCH 03/11] Update Fraction.js --- Maths/Fraction.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Maths/Fraction.js b/Maths/Fraction.js index 766b944fe7..5d4da33a2b 100644 --- a/Maths/Fraction.js +++ b/Maths/Fraction.js @@ -4,7 +4,8 @@ * @param {number} num - a float type number is expected, but an integer will also work. * @param {number} accuracy - the accuracy of the fraction, the default is 6. * @return {Array} - an array containing the numerator and denominator of the fraction. - * @see https://en.wikipedia.org/wiki/Repeating_decimal and @see https://en.wikipedia.org/wiki/Decimal#Decimal_fractions + * @see https://en.wikipedia.org/wiki/Repeating_decimal and + * @see https://en.wikipedia.org/wiki/Decimal#Decimal_fractions * @example fraction(0.5) // [1, 2] * @example fraction(0.3333333333333333) // [1, 3] * @example fraction(0.25) // [1, 4] From 2abb00d597303538dab38f45a115cce6384c73fb Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Tue, 10 Oct 2023 11:11:37 +0600 Subject: [PATCH 04/11] Update Fraction.js --- Maths/Fraction.js | 89 ++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/Maths/Fraction.js b/Maths/Fraction.js index 5d4da33a2b..dcf687fb75 100644 --- a/Maths/Fraction.js +++ b/Maths/Fraction.js @@ -2,7 +2,7 @@ * @function fraction * @description This function returns the fraction of a float type number. * @param {number} num - a float type number is expected, but an integer will also work. - * @param {number} accuracy - the accuracy of the fraction, the default is 6. + * @param {number} accuracy - the accuracy of the fraction, the default is 6. like if the accuracy is 2 then for 1.333 result will be 10/9, where for 6 it will return 1333/1000. * @return {Array} - an array containing the numerator and denominator of the fraction. * @see https://en.wikipedia.org/wiki/Repeating_decimal and * @see https://en.wikipedia.org/wiki/Decimal#Decimal_fractions @@ -11,57 +11,50 @@ * @example fraction(0.25) // [1, 4] * @example fraction(5.56) // [139, 25] * @example fraction(0.33) // [33, 100] + * @exapmle fraction(0.33,2) // [10, 3] */ function fraction(number, accuracy = 6) { - let inp = typeof number === "number" ? number : false; - let acc = typeof accuracy === "number" ? accuracy : false; - if (inp !== false && acc !== false) { - if (Number.isInteger(inp)) { - return [inp, 1]; - } else { - inp = inp.toString(); - let len; - let reg = inp.match(/(\d+?)\1+$/); - if (reg && reg[0].length > acc) { - let pos = inp.split("."); - inp = inp.replace(reg[0], reg[1]); - let rec = pos[0] + pos[1].replace(reg[0], ""); - inp = Number(rec + reg[1]) - Number(rec); - len = Number( - "9".repeat(reg[1].length) + "0".repeat(rec.length - pos[0].length) - ); + let inp = typeof number === "number" ? number : () => {throw new TypeError("Invalid number, a number type value expected");}; + let acc = typeof accuracy === "number" && accuracy >= 1 && accuracy <= 16 ? accuracy : () => {throw new TypeError("Invalid accuracy, a integer type value expected between 1 - 16");} + if (Number.isInteger(inp)) { + return [inp, 1]; } else { - inp = inp.replace(".", ""); - len = 10 ** (inp.length - 1); - inp = Number(inp); - } - let d = true; - while (d) { - if (inp % 5 == 0 && len % 5 == 0) { - inp /= 5; - len /= 5; - } else if (inp % 2 == 0 && len % 2 == 0) { - inp /= 2; - len /= 2; - } else if (inp % 3 == 0 && len % 3 == 0) { - inp /= 3; - len /= 3; - } else if (inp % 7 == 0 && len % 7 == 0) { - inp /= 7; - len /= 7; + inp = inp.toString(); + let len; + let reg = inp.match(/(\d+?)\1+$/); + if (reg && reg[0].length > acc) { + let pos = inp.split("."); + inp = inp.replace(reg[0], reg[1]); + let rec = pos[0] + pos[1].replace(reg[0], ""); + inp = Number(rec + reg[1]) - Number(rec); + len = Number( + "9".repeat(reg[1].length) + "0".repeat(rec.length - pos[0].length) + ); } else { - d = false; + inp = inp.replace(".", ""); + len = 10 ** (inp.length - 1); + inp = Number(inp); + } + let d = true; + while (d) { + if (inp % 5 == 0 && len % 5 == 0) { + inp /= 5; + len /= 5; + } else if (inp % 2 == 0 && len % 2 == 0) { + inp /= 2; + len /= 2; + } else if (inp % 3 == 0 && len % 3 == 0) { + inp /= 3; + len /= 3; + } else if (inp % 7 == 0 && len % 7 == 0) { + inp /= 7; + len /= 7; + } else { + d = false; + } } + return [inp, len]; } - return [inp, len]; - } - } else { - if (inp === false) { - throw new TypeError("Invalid number"); - } else { - throw new TypeError("Invalid accuracy"); - } } -} - -export { fraction }; + + export { fraction }; From 560127f0844cbc630719d92ffbb0ab571372c4fa Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Tue, 10 Oct 2023 11:16:17 +0600 Subject: [PATCH 05/11] fixing spelling Fraction.js --- Maths/Fraction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maths/Fraction.js b/Maths/Fraction.js index dcf687fb75..ed00f79c33 100644 --- a/Maths/Fraction.js +++ b/Maths/Fraction.js @@ -11,7 +11,7 @@ * @example fraction(0.25) // [1, 4] * @example fraction(5.56) // [139, 25] * @example fraction(0.33) // [33, 100] - * @exapmle fraction(0.33,2) // [10, 3] + * @example fraction(0.33,2) // [10, 3] */ function fraction(number, accuracy = 6) { let inp = typeof number === "number" ? number : () => {throw new TypeError("Invalid number, a number type value expected");}; From 82fd7fcb0bb5583d9036b23d2e950e881e24766a Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Tue, 10 Oct 2023 21:39:55 +0600 Subject: [PATCH 06/11] Update Fraction.js --- Maths/Fraction.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Maths/Fraction.js b/Maths/Fraction.js index ed00f79c33..ab08d3bacf 100644 --- a/Maths/Fraction.js +++ b/Maths/Fraction.js @@ -14,10 +14,11 @@ * @example fraction(0.33,2) // [10, 3] */ function fraction(number, accuracy = 6) { + let returnVal = []; let inp = typeof number === "number" ? number : () => {throw new TypeError("Invalid number, a number type value expected");}; let acc = typeof accuracy === "number" && accuracy >= 1 && accuracy <= 16 ? accuracy : () => {throw new TypeError("Invalid accuracy, a integer type value expected between 1 - 16");} if (Number.isInteger(inp)) { - return [inp, 1]; + returnVal = [inp, 1]; } else { inp = inp.toString(); let len; @@ -53,8 +54,9 @@ function fraction(number, accuracy = 6) { d = false; } } - return [inp, len]; + returnVal= [inp, len]; } + return returnVal; } export { fraction }; From be441e7c6178ed9178d26dca060e02433ab02bbe Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Fri, 13 Oct 2023 06:56:19 +0600 Subject: [PATCH 07/11] Updated Fraction.js --- Maths/Fraction.js | 91 +++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/Maths/Fraction.js b/Maths/Fraction.js index ab08d3bacf..ff414b9ba9 100644 --- a/Maths/Fraction.js +++ b/Maths/Fraction.js @@ -14,49 +14,54 @@ * @example fraction(0.33,2) // [10, 3] */ function fraction(number, accuracy = 6) { - let returnVal = []; - let inp = typeof number === "number" ? number : () => {throw new TypeError("Invalid number, a number type value expected");}; - let acc = typeof accuracy === "number" && accuracy >= 1 && accuracy <= 16 ? accuracy : () => {throw new TypeError("Invalid accuracy, a integer type value expected between 1 - 16");} - if (Number.isInteger(inp)) { - returnVal = [inp, 1]; - } else { - inp = inp.toString(); + if (typeof number === "number" && Number.isNaN(number) && Number.isFinite(number) + && typeof accuracy === "number" && Number.isNaN(accuracy) && accuracy >= 1 && accuracy <= 16) { + let neg = 1; + // if number is negative then following code will run + if (number < 0) { + neg = -1; + number = Math.abs(number); + } + // if number is 0 then it will return [0, 1] + if (number === 0) return [0, 1]; + if (Number.isInteger(number)) return [neg * number, 1]; + // if number is not an integer then follwing code will run + number = number.toString(); let len; - let reg = inp.match(/(\d+?)\1+$/); - if (reg && reg[0].length > acc) { - let pos = inp.split("."); - inp = inp.replace(reg[0], reg[1]); - let rec = pos[0] + pos[1].replace(reg[0], ""); - inp = Number(rec + reg[1]) - Number(rec); - len = Number( - "9".repeat(reg[1].length) + "0".repeat(rec.length - pos[0].length) - ); + let reg = number.match(/(\d+?)\1+$/); + // if number is repeating decimal then following code will run + if (reg && reg[0].length > accuracy) { + let pos = number.split("."); + number = number.replace(reg[0], reg[1]); + let rec = pos[0] + pos[1].replace(reg[0], ""); + number = Number(rec + reg[1]) - Number(rec); + len = Number( + "9".repeat(reg[1].length) + "0".repeat(rec.length - pos[0].length) + ); } else { - inp = inp.replace(".", ""); - len = 10 ** (inp.length - 1); - inp = Number(inp); - } - let d = true; - while (d) { - if (inp % 5 == 0 && len % 5 == 0) { - inp /= 5; - len /= 5; - } else if (inp % 2 == 0 && len % 2 == 0) { - inp /= 2; - len /= 2; - } else if (inp % 3 == 0 && len % 3 == 0) { - inp /= 3; - len /= 3; - } else if (inp % 7 == 0 && len % 7 == 0) { - inp /= 7; - len /= 7; - } else { - d = false; - } + // if number is not repeating decimal then following code will run + number = number.replace(".", ""); + len = 10 ** (number.length - 1); + number = Number(number); } - returnVal= [inp, len]; - } - return returnVal; - } - - export { fraction }; + // it will findout the gcd of number and len to reduce the fraction nomitor and denominator like 4/8 will be 1/2 + let div = gcd(number, len); + number /= div; + len /= div; + return [neg * number, len]; + } else { + if (typeof number !== "number") throw new TypeError("Invalid number, a number type value expected"); + if (typeof accuracy !== "number") throw new TypeError("Invalid accuracy, a number type value expected"); + if (Number.isNaN(number)) throw new TypeError("Invalid number, a number type value expected"); + if (Number.isNaN(accuracy)) throw new TypeError("Invalid accuracy, a number type value expected"); + if (!Number.isFinite(number)) throw new RangeError("Invalid number, a finite number expected"); + if (accuracy < 1 || accuracy > 16) throw new RangeError("Invalid accuracy, a integer type value expected between 1 and 16"); + } +} + +function gcd(a, b) { + if (b == 0) return a; + return gcd(b, a % b); +} + +export { fraction }; From 1e2000d186c1ec6d81f85f65d70d03bbc732b349 Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Fri, 13 Oct 2023 07:00:21 +0600 Subject: [PATCH 08/11] Update spelling in Fraction.js --- Maths/Fraction.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Maths/Fraction.js b/Maths/Fraction.js index ff414b9ba9..c919b84f35 100644 --- a/Maths/Fraction.js +++ b/Maths/Fraction.js @@ -17,19 +17,19 @@ function fraction(number, accuracy = 6) { if (typeof number === "number" && Number.isNaN(number) && Number.isFinite(number) && typeof accuracy === "number" && Number.isNaN(accuracy) && accuracy >= 1 && accuracy <= 16) { let neg = 1; - // if number is negative then following code will run + // if number is a negative then following code will run if (number < 0) { neg = -1; number = Math.abs(number); } - // if number is 0 then it will return [0, 1] + // if number is a 0 then it will return [0, 1] if (number === 0) return [0, 1]; if (Number.isInteger(number)) return [neg * number, 1]; - // if number is not an integer then follwing code will run + // if number is a not an integer then follwing code will run number = number.toString(); let len; let reg = number.match(/(\d+?)\1+$/); - // if number is repeating decimal then following code will run + // if number is a repeating decimal then following code will run if (reg && reg[0].length > accuracy) { let pos = number.split("."); number = number.replace(reg[0], reg[1]); @@ -39,12 +39,12 @@ function fraction(number, accuracy = 6) { "9".repeat(reg[1].length) + "0".repeat(rec.length - pos[0].length) ); } else { - // if number is not repeating decimal then following code will run + // if number is not a repeating decimal then following code will run number = number.replace(".", ""); len = 10 ** (number.length - 1); number = Number(number); } - // it will findout the gcd of number and len to reduce the fraction nomitor and denominator like 4/8 will be 1/2 + // it will find out the gcd of the number and the len to reduce the fraction nomitor and denominator like 4/8 will be 1/2 let div = gcd(number, len); number /= div; len /= div; From aa71162848b1926af628c8f9ace606f5aa7c2a13 Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Fri, 13 Oct 2023 07:03:05 +0600 Subject: [PATCH 09/11] =?UTF-8?q?Oh!=20spelling.=F0=9F=98=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Maths/Fraction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maths/Fraction.js b/Maths/Fraction.js index c919b84f35..7b00573c67 100644 --- a/Maths/Fraction.js +++ b/Maths/Fraction.js @@ -25,7 +25,7 @@ function fraction(number, accuracy = 6) { // if number is a 0 then it will return [0, 1] if (number === 0) return [0, 1]; if (Number.isInteger(number)) return [neg * number, 1]; - // if number is a not an integer then follwing code will run + // if number is a not an integer then following code will run number = number.toString(); let len; let reg = number.match(/(\d+?)\1+$/); From c33f80e8423187fcf6430ba9c45809adce261aa5 Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Fri, 13 Oct 2023 07:04:34 +0600 Subject: [PATCH 10/11] Update Fraction.test.js --- Maths/test/Fraction.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Maths/test/Fraction.test.js b/Maths/test/Fraction.test.js index 05547ea426..5b2f162cc3 100644 --- a/Maths/test/Fraction.test.js +++ b/Maths/test/Fraction.test.js @@ -10,6 +10,9 @@ describe('Fraction', () => { it('should return [1, 4] for 0.25', () => { expect(fraction(0.25)).toEqual([1, 4]); }); + it('should return [0, 1] for 0', () => { + expect(fraction(0)).toEqual([0, 1]); + }); it('should return [139, 25] for 5.56', () => { expect(fraction(5.56)).toEqual([139, 25]); }); From ca69ae39180ad10c116c29df951f1dc17eca5987 Mon Sep 17 00:00:00 2001 From: maruf hasan Date: Fri, 13 Oct 2023 07:12:26 +0600 Subject: [PATCH 11/11] logical error fixed. --- Maths/Fraction.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Maths/Fraction.js b/Maths/Fraction.js index 7b00573c67..ac9dcd5852 100644 --- a/Maths/Fraction.js +++ b/Maths/Fraction.js @@ -14,8 +14,8 @@ * @example fraction(0.33,2) // [10, 3] */ function fraction(number, accuracy = 6) { - if (typeof number === "number" && Number.isNaN(number) && Number.isFinite(number) - && typeof accuracy === "number" && Number.isNaN(accuracy) && accuracy >= 1 && accuracy <= 16) { + if (typeof number === "number" && !Number.isNaN(number) && Number.isFinite(number) + && typeof accuracy === "number" && !Number.isNaN(accuracy) && accuracy >= 1 && accuracy <= 16) { let neg = 1; // if number is a negative then following code will run if (number < 0) {