77 lines
1.7 KiB
JavaScript
77 lines
1.7 KiB
JavaScript
(() => {
|
|
"use strict";
|
|
|
|
// ---------------- APPROXIMATE RATIO ----------------
|
|
|
|
// approxRatio :: Real -> Real -> Ratio
|
|
const approxRatio = epsilon =>
|
|
n => {
|
|
const
|
|
c = gcdApprox(
|
|
0 < epsilon
|
|
? epsilon
|
|
: (1 / 10000)
|
|
)(1, n);
|
|
|
|
return Ratio(
|
|
Math.floor(n / c),
|
|
Math.floor(1 / c)
|
|
);
|
|
};
|
|
|
|
|
|
// gcdApprox :: Real -> (Real, Real) -> Real
|
|
const gcdApprox = epsilon =>
|
|
(x, y) => {
|
|
const _gcd = (a, b) =>
|
|
b < epsilon
|
|
? a
|
|
: _gcd(b, a % b);
|
|
|
|
return _gcd(Math.abs(x), Math.abs(y));
|
|
};
|
|
|
|
|
|
// ---------------------- TEST -----------------------
|
|
// main :: IO ()
|
|
const main = () =>
|
|
// Using a tolerance of 1/10000
|
|
[0.9054054, 0.518518, 0.75]
|
|
.map(
|
|
compose(
|
|
showRatio,
|
|
approxRatio(0.0001)
|
|
)
|
|
)
|
|
.join("\n");
|
|
|
|
|
|
// ---------------- GENERIC FUNCTIONS ----------------
|
|
|
|
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
|
const compose = (...fs) =>
|
|
// A function defined by the right-to-left
|
|
// composition of all the functions in fs.
|
|
fs.reduce(
|
|
(f, g) => x => f(g(x)),
|
|
x => x
|
|
);
|
|
|
|
|
|
// Ratio :: Int -> Int -> Ratio
|
|
const Ratio = (n, d) => ({
|
|
type: "Ratio",
|
|
n,
|
|
d
|
|
});
|
|
|
|
|
|
// showRatio :: Ratio -> String
|
|
const showRatio = nd =>
|
|
`${nd.n.toString()}/${nd.d.toString()}`;
|
|
|
|
|
|
// MAIN ---
|
|
return main();
|
|
})();
|