57 lines
1.3 KiB
JavaScript
57 lines
1.3 KiB
JavaScript
(() => {
|
|
|
|
// -------------- ROMAN NUMERALS DECODED ---------------
|
|
|
|
// Folding from right to left,
|
|
// lower leftward characters are subtracted,
|
|
// others are added.
|
|
|
|
// fromRoman :: String -> Int
|
|
const fromRoman = s =>
|
|
foldr(l => ([r, n]) => [
|
|
l,
|
|
l >= r ? (
|
|
n + l
|
|
) : n - l
|
|
])([0, 0])(
|
|
[...s].map(charVal)
|
|
)[1];
|
|
|
|
// charVal :: Char -> Maybe Int
|
|
const charVal = k => {
|
|
const v = {
|
|
I: 1,
|
|
V: 5,
|
|
X: 10,
|
|
L: 50,
|
|
C: 100,
|
|
D: 500,
|
|
M: 1000
|
|
} [k];
|
|
return v !== undefined ? v : 0;
|
|
};
|
|
|
|
// ----------------------- TEST ------------------------
|
|
const main = () => [
|
|
'MDCLXVI', 'MCMXC', 'MMVIII', 'MMXVI', 'MMXVII'
|
|
]
|
|
.map(fromRoman)
|
|
.join('\n');
|
|
|
|
|
|
// ----------------- GENERIC FUNCTIONS -----------------
|
|
|
|
// foldr :: (a -> b -> b) -> b -> [a] -> b
|
|
const foldr = f =>
|
|
// Note that that the Haskell signature of foldr
|
|
// differs from that of foldl - the positions of
|
|
// accumulator and current value are reversed.
|
|
a => xs => [...xs].reduceRight(
|
|
(a, x) => f(x)(a),
|
|
a
|
|
);
|
|
|
|
// MAIN ---
|
|
return main();
|
|
})();
|