From 14e8866b58a7af421eff85eb1168986a18b81221 Mon Sep 17 00:00:00 2001 From: Eric Lavault <39483232+lvlte@users.noreply.github.com> Date: Thu, 14 Oct 2021 12:45:35 +0200 Subject: [PATCH 1/7] Add Math function for representing the decimal expansion of a given fraction (decimal or any base from 2 to 10). --- Maths/DecimalExpansion.js | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Maths/DecimalExpansion.js diff --git a/Maths/DecimalExpansion.js b/Maths/DecimalExpansion.js new file mode 100644 index 0000000000..e0e3beec35 --- /dev/null +++ b/Maths/DecimalExpansion.js @@ -0,0 +1,68 @@ +/** + * @author Eric Lavault + * @license MIT + * + * Represents the decimal (or binary, octal, any base from 2 to 10) expansion + * of a/b using euclidean division. + * + * Because this function is recursive, it may throw an error when reaching the + * maximum call stack size. + * + * Returns an array containing : [ + * 0: integer part of the division + * 1: array of decimals (if any, or an empty array) + * 2: indexOf 1st cycle digit in decimals array if a/b is periodic, or undef. + * ] + * + * @see https://mathworld.wolfram.com/DecimalExpansion.html + * + * @param {number} a + * @param {number} b + * @param {number} [base=10] + * @returns {array} + */ +export function decExp (a, b, base = 10, exp = [], d = {}, dlen = 0) { + if (base < 2 || base > 10) { + throw new RangeError('Unsupported base. Must be in range [2, 10]') + } + + if (a === 0) { + return [0, [], undefined] + } + + if (a === b && dlen === 0) { + return [1, [], undefined] + } + + // d contains the dividends used so far and the corresponding index of its + // euclidean division by b in the expansion array. + d[a] = dlen++ + + if (a < b) { + exp.push(0) + return decExp(a * base, b, base, exp, d, dlen) + } + + // Euclid's division lemma : a = bq + r + const r = a % b + const q = (a - r) / b + + // Decimal expansion (1st element is the integer part) + exp.push(+q.toString(base)) + + if (r === 0) { + // got a regular number (division terminates) + return [exp[0], exp.slice(1), undefined] + } + + // For the next iteration + a = r * base + + // Check if `a` has already been used as a dividend, in which case it means + // the expansion is periodic. + if (a in d) { + return [exp[0], exp.slice(1), d[a] - 1] + } + + return decExp(a, b, base, exp, d, dlen) +} From f5756e99985bb38eb7630f8f41d9b9c20da3ea05 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 14 Oct 2021 10:46:46 +0000 Subject: [PATCH 2/7] Auto-update DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 8290405c9a..1987bb2938 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -144,6 +144,7 @@ * [CheckKishnamurthyNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/CheckKishnamurthyNumber.js) * [Coordinate](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Coordinate.js) * [CoPrimeCheck](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/CoPrimeCheck.js) + * [DecimalExpansion](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DecimalExpansion.js) * [decimalIsolate](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/decimalIsolate.js) * [DegreeToRadian](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DegreeToRadian.js) * [DigitSum](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DigitSum.js) From d0341d60bad531df2ef0db144d64d96fb0e21989 Mon Sep 17 00:00:00 2001 From: Eric Lavault <39483232+lvlte@users.noreply.github.com> Date: Thu, 14 Oct 2021 13:27:38 +0200 Subject: [PATCH 3/7] DecimalExpansion Jest tests. --- Maths/test/DecimalExpansion.test.js | 192 ++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 Maths/test/DecimalExpansion.test.js diff --git a/Maths/test/DecimalExpansion.test.js b/Maths/test/DecimalExpansion.test.js new file mode 100644 index 0000000000..afc7243ba4 --- /dev/null +++ b/Maths/test/DecimalExpansion.test.js @@ -0,0 +1,192 @@ +import { decExp } from '../DecimalExpansion' + +/** + * Decimal + */ + +describe('Finite Decimal Expansion', () => { + it('1/2 = 0.5', () => { + const [integer, decimals, cycleIndex] = decExp(1, 2) + expect(integer).toBe(0) + expect(decimals).toEqual([5]) + expect(cycleIndex).toBeUndefined() + }) + + it('1/5 = 0.2', () => { + const [integer, decimals, cycleIndex] = decExp(1, 5) + expect(integer).toBe(0) + expect(decimals).toEqual([2]) + expect(cycleIndex).toBeUndefined() + }) + + it('1/8 = 0.125', () => { + const [integer, decimals, cycleIndex] = decExp(1, 8) + expect(integer).toBe(0) + expect(decimals).toEqual([1, 2, 5]) + expect(cycleIndex).toBeUndefined() + }) + + it('255/40 = 6.375', () => { + const [integer, decimals, cycleIndex] = decExp(255, 40) + expect(integer).toBe(6) + expect(decimals).toEqual([3, 7, 5]) + expect(cycleIndex).toBeUndefined() + }) +}) + +describe('Repeating Decimal Expansion', () => { + it('1/3 = 0.(3)', () => { + expect(decExp(1, 3)).toStrictEqual([0, [3], 0]) + }) + + it('1/6 = 0.1(6)', () => { + expect(decExp(1, 6)).toStrictEqual([0, [1, 6], 1]) + }) + + it('1/7 = 0.(142857)', () => { + expect(decExp(1, 7)).toStrictEqual([0, [1, 4, 2, 8, 5, 7], 0]) + }) +}) + +/** + * Binary + */ + +describe('Finite Binary Expansion', () => { + it('1/2 = 0.1₂', () => { + const [integer, decimals, cycleIndex] = decExp(1, 2, 2) + expect(integer).toBe(0) + expect(decimals).toEqual([1]) + expect(cycleIndex).toBeUndefined() + }) + + it('1/8 = 0.001₂', () => { + const [integer, decimals, cycleIndex] = decExp(1, 8, 2) + expect(integer).toBe(0) + expect(decimals).toEqual([0, 0, 1]) + expect(cycleIndex).toBeUndefined() + }) + + it('255/40 = 110.011₂', () => { + const [integer, decimals, cycleIndex] = decExp(255, 40, 2) + expect(integer).toBe(110) + expect(decimals).toEqual([0, 1, 1]) + expect(cycleIndex).toBeUndefined() + }) +}) + +describe('Repeating Binary Expansion', () => { + it('1/3 = 0.(01)₂', () => { + expect(decExp(1, 3, 2)).toStrictEqual([0, [0, 1], 0]) + }) + + it('1/5 = 0.(0011)₂', () => { + expect(decExp(1, 5, 2)).toStrictEqual([0, [0, 0, 1, 1], 0]) + }) + + it('1/6 = 0.0(01)₂', () => { + expect(decExp(1, 6, 2)).toStrictEqual([0, [0, 0, 1], 1]) + }) + + it('1/7 = 0.(001)₂', () => { + expect(decExp(1, 7, 2)).toStrictEqual([0, [0, 0, 1], 0]) + }) +}) + +/** + * Octal + */ + +describe('Finite Octal Expansion', () => { + it('1/2 = 0.4₈', () => { + const [integer, decimals, cycleIndex] = decExp(1, 2, 8) + expect(integer).toBe(0) + expect(decimals).toEqual([4]) + expect(cycleIndex).toBeUndefined() + }) + + it('1/8 = 0.1₈', () => { + const [integer, decimals, cycleIndex] = decExp(1, 8, 8) + expect(integer).toBe(0) + expect(decimals).toEqual([1]) + expect(cycleIndex).toBeUndefined() + }) + + it('255/40 = 6.3₈', () => { + const [integer, decimals, cycleIndex] = decExp(255, 40, 8) + expect(integer).toBe(6) + expect(decimals).toEqual([3]) + expect(cycleIndex).toBeUndefined() + }) +}) + +describe('Repeating Octal Expansion', () => { + it('1/3 = 0.(25)₈', () => { + expect(decExp(1, 3, 8)).toStrictEqual([0, [2, 5], 0]) + }) + + it('1/5 = 0.(1463)₈', () => { + expect(decExp(1, 5, 8)).toStrictEqual([0, [1, 4, 6, 3], 0]) + }) + + it('1/6 = 0.1(25)₈', () => { + expect(decExp(1, 6, 8)).toStrictEqual([0, [1, 2, 5], 1]) + }) + + it('1/7 = 0.(1)₈', () => { + expect(decExp(1, 7, 8)).toStrictEqual([0, [1], 0]) + }) +}) + +/** + * Integers + */ + +describe('Integers', () => { + it('1/1 = 1', () => { + const [integer, decimals, cycleIndex] = decExp(1, 1) + expect(integer).toBe(1) + expect(decimals).toStrictEqual([]) + expect(cycleIndex).toBeUndefined() + }) + + it('5/5 = 1', () => { + const [integer, decimals, cycleIndex] = decExp(5, 5) + expect(integer).toBe(1) + expect(decimals).toStrictEqual([]) + expect(cycleIndex).toBeUndefined() + }) + + it('2/1 = 2', () => { + const [integer, decimals, cycleIndex] = decExp(2, 1) + expect(integer).toBe(2) + expect(decimals).toStrictEqual([]) + expect(cycleIndex).toBeUndefined() + }) + + it('9/3 = 3', () => { + const [integer, decimals, cycleIndex] = decExp(9, 3) + expect(integer).toBe(3) + expect(decimals).toStrictEqual([]) + expect(cycleIndex).toBeUndefined() + }) +}) + +/** + * Unsupported base + */ + +describe('Throws on unsupported base', () => { + it('negative base', () => { + expect(() => decExp(1, 1, -2)).toThrow(RangeError) + }) + it('base 0', () => { + expect(() => decExp(1, 1, 0)).toThrow(RangeError) + }) + it('base 1', () => { + expect(() => decExp(1, 1, 1)).toThrow(RangeError) + }) + it('base 11', () => { + expect(() => decExp(1, 1, 11)).toThrow(RangeError) + }) +}) From b9e6793be28913d00323b651f3d8184ca4f0393b Mon Sep 17 00:00:00 2001 From: Rak Laptudirm Date: Sat, 2 Apr 2022 20:32:07 +0530 Subject: [PATCH 4/7] chore: trigger update --- DIRECTORY.md | 1 - 1 file changed, 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 1987bb2938..8290405c9a 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -144,7 +144,6 @@ * [CheckKishnamurthyNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/CheckKishnamurthyNumber.js) * [Coordinate](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Coordinate.js) * [CoPrimeCheck](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/CoPrimeCheck.js) - * [DecimalExpansion](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DecimalExpansion.js) * [decimalIsolate](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/decimalIsolate.js) * [DegreeToRadian](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DegreeToRadian.js) * [DigitSum](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DigitSum.js) From 7c2ac748d2fb836de081d6277275ba704ebcba98 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 2 Apr 2022 15:02:39 +0000 Subject: [PATCH 5/7] Auto-update DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 8290405c9a..1987bb2938 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -144,6 +144,7 @@ * [CheckKishnamurthyNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/CheckKishnamurthyNumber.js) * [Coordinate](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Coordinate.js) * [CoPrimeCheck](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/CoPrimeCheck.js) + * [DecimalExpansion](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DecimalExpansion.js) * [decimalIsolate](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/decimalIsolate.js) * [DegreeToRadian](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DegreeToRadian.js) * [DigitSum](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/DigitSum.js) From fb0564ed0adada419beb1f555b0615e82d1f4bb2 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 2 Apr 2022 15:04:24 +0000 Subject: [PATCH 6/7] Auto-update DIRECTORY.md --- DIRECTORY.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 0802e454ab..8613c684c8 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -18,6 +18,8 @@ * [LFUCache](https://github.com/TheAlgorithms/Javascript/blob/master/Cache/LFUCache.js) * [LRUCache](https://github.com/TheAlgorithms/Javascript/blob/master/Cache/LRUCache.js) * [Memoize](https://github.com/TheAlgorithms/Javascript/blob/master/Cache/Memoize.js) + * test + * [cacheTest](https://github.com/TheAlgorithms/Javascript/blob/master/Cache/test/cacheTest.js) ## Cellular-Automata * [ConwaysGameOfLife](https://github.com/TheAlgorithms/Javascript/blob/master/Cellular-Automata/ConwaysGameOfLife.js) @@ -65,11 +67,13 @@ * Graph * [Graph](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Graph/Graph.js) * [Graph2](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Graph/Graph2.js) + * [Graph3](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Graph/Graph3.js) * Heap * [MaxHeap](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Heap/MaxHeap.js) * [MinHeap](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Heap/MinHeap.js) * [MinPriorityQueue](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Heap/MinPriorityQueue.js) * Linked-List + * [AddTwoNumbers](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/AddTwoNumbers.js) * [CycleDetection](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/CycleDetection.js) * [DoublyLinkedList](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/DoublyLinkedList.js) * [RotateListRight](https://github.com/TheAlgorithms/Javascript/blob/master/Data-Structures/Linked-List/RotateListRight.js) @@ -143,6 +147,7 @@ * [Abs](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Abs.js) * [AliquotSum](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/AliquotSum.js) * [Area](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/Area.js) + * [ArithmeticGeometricMean](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/ArithmeticGeometricMean.js) * [ArmstrongNumber](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/ArmstrongNumber.js) * [AverageMean](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/AverageMean.js) * [AverageMedian](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/AverageMedian.js) @@ -169,6 +174,7 @@ * [FindHcf](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/FindHcf.js) * [FindLcm](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/FindLcm.js) * [FindMin](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/FindMin.js) + * [FindMinIterator](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/FindMinIterator.js) * [GetEuclidGCD](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/GetEuclidGCD.js) * [GridGet](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/GridGet.js) * [IsDivisible](https://github.com/TheAlgorithms/Javascript/blob/master/Maths/IsDivisible.js) @@ -291,6 +297,7 @@ * [AlternativeStringArrange](https://github.com/TheAlgorithms/Javascript/blob/master/String/AlternativeStringArrange.js) * [CheckAnagram](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckAnagram.js) * [CheckCamelCase](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckCamelCase.js) + * [CheckExceeding](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckExceeding.js) * [CheckFlatCase](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckFlatCase.js) * [CheckKebabCase](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckKebabCase.js) * [CheckPalindrome](https://github.com/TheAlgorithms/Javascript/blob/master/String/CheckPalindrome.js) From 993f1cd26b1a8afd5fd6f2abc3e7a794cb923af3 Mon Sep 17 00:00:00 2001 From: Rak Laptudirm Date: Sat, 2 Apr 2022 20:37:03 +0530 Subject: [PATCH 7/7] chore: trigger checks --- Maths/DecimalExpansion.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Maths/DecimalExpansion.js b/Maths/DecimalExpansion.js index e0e3beec35..6f699ba479 100644 --- a/Maths/DecimalExpansion.js +++ b/Maths/DecimalExpansion.js @@ -1,6 +1,5 @@ /** * @author Eric Lavault - * @license MIT * * Represents the decimal (or binary, octal, any base from 2 to 10) expansion * of a/b using euclidean division.