diff --git a/5kyu/common-denominators/description.md b/5kyu/common-denominators/description.md new file mode 100644 index 0000000..c4a1bc1 --- /dev/null +++ b/5kyu/common-denominators/description.md @@ -0,0 +1,32 @@ +Common denominators + +You will have a list of rationals in the form + +`{ {numer_1, denom_1} , ... {numer_n, denom_n} } ` +or +`[ [numer_1, denom_1] , ... [numer_n, denom_n] ] ` +or +`[ (numer_1, denom_1) , ... (numer_n, denom_n) ] ` +where all numbers are positive ints. You have to produce a result in the form: + +`(N_1, D) ... (N_n, D)` +or +`[ [N_1, D] ... [N_n, D] ]` +or +`[ (N_1', D) , ... (N_n, D) ]` +or +`{{N_1, D} ... {N_n, D}}` +or +`"(N_1, D) ... (N_n, D)"` +depending on the language (See Example tests) in which D is as small as possible and + +`N_1/D == numer_1/denom_1 ... N_n/D == numer_n,/denom_n.` +Example: +`convertFracs [(1, 2), (1, 3), (1, 4)] `shouldBe` [(6, 12), (4, 12), (3, 12)]` +Note: +Due to the fact that the first translations were written long ago - more than 6 years - these first translations have only irreducible fractions. + +Newer translations have some reducible fractions. To be on the safe side it is better to do a bit more work by simplifying fractions even if they don't have to be. + +Note for Bash: +input is a string, e.g `"2,4,2,6,2,8"` output is then `"6 12 4 12 3 12"` \ No newline at end of file diff --git a/5kyu/common-denominators/solution.ts b/5kyu/common-denominators/solution.ts new file mode 100644 index 0000000..c374224 --- /dev/null +++ b/5kyu/common-denominators/solution.ts @@ -0,0 +1,32 @@ +/** + * Finds the greatest common divisor of two numbers + * using Euclid's algorithm. + */ +const gcd = (a: number, b: number): number => { + return a === 0 ? b : gcd(b % a, a); +} + +/** + * Finds the least common multiple of two numbers. + */ +const lcm = (a: number, b: number): number => { + return a * b / gcd(a, b); +} + +/** + * Simplifies a fraction to its simplest form. + */ +const simplify = (numerator: number, denominator: number): [number, number] => { + const divisor = gcd(numerator, denominator); + return [numerator / divisor, denominator / divisor]; +} + +export const convertFrac = (lst: [number, number][]): string => { + const simplifiedList = lst.map(([numerator, denominator]) => simplify(numerator, denominator)); + // find the least common multiple of all the denominators + const lcmDenominator = simplifiedList.reduce((acc, [_, denominator]) => lcm(acc, denominator), 1); + return simplifiedList + .map(([numerator, denominator]) => [numerator * lcmDenominator / denominator, lcmDenominator]) + .map(([numerator, denominator]) => `(${numerator},${denominator})`) + .join(''); +} \ No newline at end of file diff --git a/5kyu/common-denominators/tests.ts b/5kyu/common-denominators/tests.ts new file mode 100644 index 0000000..1e8342a --- /dev/null +++ b/5kyu/common-denominators/tests.ts @@ -0,0 +1,19 @@ +import { convertFrac } from './solution'; +import { assert } from "chai"; + +describe("Fixed Tests", function () { + it("Basic tests convertFrac", function () { + assert.strictEqual( + convertFrac([[1, 2], [1, 3], [1, 4]]), + "(6,12)(4,12)(3,12)" + ); + assert.strictEqual( + convertFrac([[69, 130], [87, 1310], [3, 4]]), + "(18078,34060)(2262,34060)(25545,34060)" + ); + assert.strictEqual( + convertFrac([[1, 2], [4, 5], [3, 4], [6, 9], [7, 10]]), + "(30,60)(48,60)(45,60)(40,60)(42,60)" + ); + }); +}); \ No newline at end of file