65 lines
1.7 KiB
JavaScript
65 lines
1.7 KiB
JavaScript
(() => {
|
|
"use strict";
|
|
|
|
// ----------------- RANGE EXPANSION -----------------
|
|
|
|
// rangeExpansion :: String -> [Int]
|
|
const rangeExpansion = rangeString =>
|
|
// A list of integers parsed from a
|
|
// comma-delimited string which may include
|
|
// (rising) hyphenated ranges.
|
|
rangeString.split(",")
|
|
.flatMap(x => {
|
|
const ns = x.split("-")
|
|
.reduce((a, s, i, xs) =>
|
|
Boolean(s) ? (
|
|
0 < i ? a.concat(
|
|
parseInt(
|
|
xs[i - 1].length ? (
|
|
s
|
|
) : `-${s}`,
|
|
10
|
|
)
|
|
) : [Number(s)]
|
|
) : a,
|
|
[]
|
|
);
|
|
|
|
return 2 === ns.length ? (
|
|
uncurry(enumFromTo)(ns)
|
|
) : ns;
|
|
});
|
|
|
|
|
|
// ---------------------- TEST -----------------------
|
|
// main :: IO ()
|
|
const main = () =>
|
|
rangeExpansion("-6,-3--1,3-5,7-11,14,15,17-20");
|
|
|
|
|
|
// --------------------- GENERIC ---------------------
|
|
|
|
// enumFromTo :: Int -> Int -> [Int]
|
|
const enumFromTo = m =>
|
|
n => Array.from({
|
|
length: 1 + n - m
|
|
}, (_, i) => m + i);
|
|
|
|
|
|
// uncurry :: (a -> b -> c) -> ((a, b) -> c)
|
|
const uncurry = f =>
|
|
// A function over a pair, derived
|
|
// from a curried function.
|
|
(...args) => {
|
|
const [x, y] = Boolean(args.length % 2) ? (
|
|
args[0]
|
|
) : args;
|
|
|
|
return f(x)(y);
|
|
};
|
|
|
|
|
|
// MAIN ---
|
|
return JSON.stringify(main());
|
|
})();
|