Department numbers: Difference between revisions

Content added Content deleted
m (→‎JS ES6: Tidied.)
Line 2,334: Line 2,334:
{{Trans|Haskell}}
{{Trans|Haskell}}
<lang JavaScript>(() => {
<lang JavaScript>(() => {
'use strict';
"use strict";


// NUMBERING CONSTRAINTS --------------------------------------------------
// -------------- NUMBERING CONSTRAINTS --------------


// options :: Int -> Int -> Int -> [(Int, Int, Int)]
// options :: Int -> Int -> Int -> [(Int, Int, Int)]
const options = (lo, hi, total) => {
const options = lo => hi => total => {
const
const
bind = flip(concatMap),
bind = xs => f => xs.flatMap(f),
ds = enumFromTo(lo, hi);
ds = enumFromTo(lo)(hi);


return bind(filter(even, ds),
return bind(ds.filter(even))(
x => bind(filter(d => d !== x, ds),
x => bind(ds.filter(d => d !== x))(
y => bind([total - (x + y)],
y => bind([total - (x + y)])(
z => (z !== y && lo <= z && z <= hi) ? [
z => (z !== y && lo <= z && z <= hi) ? [
[x, y, z]
[x, y, z]
Line 2,352: Line 2,352:
)
)
)
)
)
);
};
};


// GENERIC FUNCTIONS ------------------------------------------------------
// ---------------------- TEST -----------------------
const main = () => {
const
label = "(Police, Sanitation, Fire)",
solutions = options(1)(7)(12),
n = solutions.length,
list = solutions
.map(JSON.stringify)
.join("\n");


return (
// concatMap :: (a -> [b]) -> [a] -> [b]
`${label}\n\n${list}\n\nNumber of options: ${n}`
const concatMap = (f, xs) => [].concat.apply([], xs.map(f));
);
};

// ---------------- GENERIC FUNCTIONS ----------------


// enumFromTo :: Int -> Int -> [Int]
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
const enumFromTo = m =>
Array.from({
n => Array.from({
length: Math.floor(n - m) + 1
length: 1 + n - m
}, (_, i) => m + i);
}, (_, i) => m + i);


Line 2,369: Line 2,381:
const even = n => n % 2 === 0;
const even = n => n % 2 === 0;


// filter :: (a -> Bool) -> [a] -> [a]
// MAIN ---
return main();
const filter = (f, xs) => xs.filter(f);

// flip :: (a -> b -> c) -> b -> a -> c
const flip = f => (a, b) => f.apply(null, [b, a]);

// length :: [a] -> Int
const length = xs => xs.length;

// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);

// show :: a -> String
const show = x => JSON.stringify(x) //, null, 2);

// unlines :: [String] -> String
const unlines = xs => xs.join('\n');

// TEST -------------------------------------------------------------------
const xs = options(1, 7, 12);
return '(Police, Sanitation, Fire)\n\n' +
unlines(map(show, xs)) +
'\n\nNumber of options: ' + length(xs);
})();</lang>
})();</lang>
{{Out}}
{{Out}}