RosettaCodeData/Task/Dinesmans-multiple-dwelling.../JavaScript/dinesmans-multiple-dwelling...

55 lines
1.5 KiB
JavaScript

(() => {
'use strict';
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = (f, xs) => [].concat.apply([], xs.map(f));
// range :: Int -> Int -> [Int]
const range = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
// and :: [Bool] -> Bool
const and = xs => {
let i = xs.length;
while (i--)
if (!xs[i]) return false;
return true;
}
// nubBy :: (a -> a -> Bool) -> [a] -> [a]
const nubBy = (p, xs) => {
const x = xs.length ? xs[0] : undefined;
return x !== undefined ? [x].concat(
nubBy(p, xs.slice(1)
.filter(y => !p(x, y)))
) : [];
}
// PROBLEM DECLARATION
const floors = range(1, 5);
return concatMap(b =>
concatMap(c =>
concatMap(f =>
concatMap(m =>
concatMap(s =>
and([ // CONDITIONS
nubBy((a, b) => a === b, [b, c, f, m, s]) // all floors singly occupied
.length === 5,
b !== 5, c !== 1, f !== 1, f !== 5,
m > c, Math.abs(s - f) > 1, Math.abs(c - f) > 1
]) ? [{
Baker: b,
Cooper: c,
Fletcher: f,
Miller: m,
Smith: s
}] : [],
floors), floors), floors), floors), floors);
// --> [{"Baker":3, "Cooper":2, "Fletcher":4, "Miller":5, "Smith":1}]
})();