September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,55 +1,71 @@
(() => {
'use strict';
// ROMAN INTEGER STRINGS ----------------------------------------------------
// roman :: Int -> String
const roman = n => [
[1000, "M"],
[900, "CM"],
[500, "D"],
[400, "CD"],
[100,"C"],
[90, "XC"],
[50, "L"],
[40, "XL"],
[10, "X"],
[9,"IX"],
[5, "V"],
[4, "IV"],
[1, "I"]
]
.reduce((a, lstPair) => {
const m = a.remainder,
v = lstPair[0];
return (v > m ? a : {
remainder: m % v,
roman: a.roman + Array(
Math.floor(m / v) + 1
)
.join(lstPair[1])
});
}, {
remainder: n,
roman: ''
})
.roman;
const roman = n =>
concat(snd(mapAccumL((balance, [k, v]) => {
const [q, r] = quotRem(balance, v);
return [r, q > 0 ? concat(replicate(q, k)) : ''];
}, n, [
['M', 1000],
['CM', 900],
['D', 500],
['CD', 400],
['C', 100],
['XC', 90],
['L', 50],
['XL', 40],
['X', 10],
['IX', 9],
['V', 5],
['IV', 4],
['I', 1]
])));
// TEST
// GENERIC FUNCTIONS -------------------------------------------------------
// If the input is a decimal string, pass any delimiters through
// romanTranscription :: (Int | String) -> String
const romanTranscription = a => {
if (typeof a === 'string') {
const ps = a.split(/\d+/),
dlm = ps.length > 1 ? ps[1] : undefined;
// concat :: [[a]] -> [a] | [String] -> String
const concat = xs =>
xs.length > 0 ? (() => {
const unit = typeof xs[0] === 'string' ? '' : [];
return unit.concat.apply(unit, xs);
})() : [];
return (dlm ? a.split(dlm)
.map(Number) : [a])
.map(roman)
.join(dlm);
} else return roman(a);
}
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// TEST
return [2016, 1990, 2008, "14.09.2015", 2000, 1666]
.map(romanTranscription);
// 'The mapAccumL function behaves like a combination of map and foldl;
// it applies a function to each element of a list, passing an accumulating
// parameter from left to right, and returning a final value of this
// accumulator together with the new list.' (See Hoogle)
// mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
const mapAccumL = (f, acc, xs) =>
xs.reduce((a, x) => {
const pair = f(a[0], x);
return [pair[0], a[1].concat([pair[1]])];
}, [acc, []]);
// quotRem :: Integral a => a -> a -> (a, a)
const quotRem = (m, n) => [Math.floor(m / n), m % n];
// replicate :: Int -> a -> [a]
const replicate = (n, x) =>
Array.from({
length: n
}, () => x);
// show :: a -> String
const show = (...x) =>
JSON.stringify.apply(
null, x.length > 1 ? [x[0], null, x[1]] : x
);
// snd :: (a, b) -> b
const snd = tpl => Array.isArray(tpl) ? tpl[1] : undefined;
// TEST -------------------------------------------------------------------
return show(
map(roman, [2016, 1990, 2008, 2000, 1666])
);
})();