61 lines
1.9 KiB
JavaScript
61 lines
1.9 KiB
JavaScript
(() => {
|
|
// longMonthsStartingFriday :: Int -> [Int]
|
|
const longMonthsStartingFriday = y =>
|
|
filter(m => (new Date(Date.UTC(y, m, 1)))
|
|
.getDay() === 5, [0, 2, 4, 6, 7, 9, 11]);
|
|
|
|
// Years -> YearMonths
|
|
// fullMonths :: [Int] -> [String]
|
|
const fullMonths = xs =>
|
|
foldl((a, y) => a.concat(
|
|
map(m => `${y.toString()} ${[
|
|
'January', '', 'March', '', 'May', '',
|
|
'July', 'August', '', 'October', '', 'December'
|
|
][m]}`, longMonthsStartingFriday(y))
|
|
), [], xs);
|
|
|
|
// leanYears :: [Int] -> [Int]
|
|
const leanYears = years =>
|
|
filter(y => longMonthsStartingFriday(y)
|
|
.length === 0, years);
|
|
|
|
// GENERIC ----------------------------------------------------------------
|
|
|
|
// A list of functions applied to a list of arguments
|
|
// <*> :: [(a -> b)] -> [a] -> [b]
|
|
const ap = (fs, xs) => //
|
|
[].concat.apply([], fs.map(f => //
|
|
[].concat.apply([], xs.map(x => [f(x)]))));
|
|
|
|
// enumFromTo :: Int -> Int -> [Int]
|
|
const enumFromTo = (m, n) =>
|
|
Array.from({
|
|
length: Math.floor(n - m) + 1
|
|
}, (_, i) => m + i);
|
|
|
|
// filter :: (a -> Bool) -> [a] -> [a]
|
|
const filter = (f, xs) => xs.filter(f);
|
|
|
|
// foldl :: (b -> a -> b) -> b -> [a] -> b
|
|
const foldl = (f, a, xs) => xs.reduce(f, a);
|
|
|
|
// map :: (a -> b) -> [a] -> [b]
|
|
const map = (f, xs) => xs.map(f);
|
|
|
|
// show :: a -> String
|
|
const show = x => JSON.stringify(x, null, 2);
|
|
|
|
|
|
// TEST -------------------------------------------------------------------
|
|
const [lstFullMonths, lstLeanYears] = ap(
|
|
[fullMonths, leanYears], [enumFromTo(1900, 2100)]
|
|
);
|
|
|
|
return show({
|
|
number: lstFullMonths.length,
|
|
firstFive: lstFullMonths.slice(0, 5),
|
|
lastFive: lstFullMonths.slice(-5),
|
|
leanYearCount: lstLeanYears.length
|
|
});
|
|
})();
|