RosettaCodeData/Task/Convert-decimal-number-to-r.../JavaScript/convert-decimal-number-to-r...

50 lines
1.3 KiB
JavaScript

(() => {
'use strict';
const main = () =>
showJSON(
map( // Using a tolerance epsilon of 1/10000
n => showRatio(approxRatio(0.0001)(n)),
[0.9054054, 0.518518, 0.75]
)
);
// Epsilon -> Real -> Ratio
// approxRatio :: Real -> Real -> Ratio
const approxRatio = eps => n => {
const
gcde = (e, x, y) => {
const _gcd = (a, b) => (b < e ? a : _gcd(b, a % b));
return _gcd(Math.abs(x), Math.abs(y));
},
c = gcde(Boolean(eps) ? eps : (1 / 10000), 1, n);
return Ratio(
Math.floor(n / c), // numerator
Math.floor(1 / c) // denominator
);
};
// GENERIC FUNCTIONS ----------------------------------
// Ratio :: Int -> Int -> Ratio
const Ratio = (n, d) => ({
type: 'Ratio',
'n': n, // numerator
'd': d // denominator
});
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// showJSON :: a -> String
const showJSON = x => JSON.stringify(x, null, 2);
// showRatio :: Ratio -> String
const showRatio = nd =>
nd.n.toString() + '/' + nd.d.toString();
// MAIN ---
return main();
})();