RosettaCodeData/Task/Combinations/JavaScript/combinations-6.js

62 lines
1.5 KiB
JavaScript

(() => {
'use strict';
// ------------------ COMBINATIONS -------------------
// combinations :: Int -> [a] -> [[a]]
const combinations = n =>
xs => {
const comb = n => xs => {
return 1 > n ? [
[]
] : 0 === xs.length ? (
[]
) : (() => {
const
h = xs[0],
tail = xs.slice(1);
return comb(n - 1)(tail)
.map(cons(h))
.concat(comb(n)(tail));
})()
};
return comb(n)(xs);
};
// ---------------------- TEST -----------------------
const main = () =>
show(
combinations(3)(
enumFromTo(0)(4)
)
);
// ---------------- GENERIC FUNCTIONS ----------------
// cons :: a -> [a] -> [a]
const cons = x =>
// A list constructed from the item x,
// followed by the existing list xs.
xs => [x].concat(xs);
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => !isNaN(m) ? (
Array.from({
length: 1 + n - m
}, (_, i) => m + i)
) : enumFromTo_(m)(n);
// show :: a -> String
const show = (...x) =>
JSON.stringify.apply(
null, x.length > 1 ? [x[0], null, x[1]] : x
);
// MAIN ---
return main();
})();