62 lines
1.8 KiB
JavaScript
62 lines
1.8 KiB
JavaScript
const compose = (...fn) => (...x) => fn.reduce((a, b) => c => a(b(c)))(...x);
|
|
const inv = b => !b;
|
|
const arrJoin = str => arr => arr.join(str);
|
|
const mkArr = (l, f) => Array(l).fill(f);
|
|
const sumArr = arr => arr.reduce((a, b) => a + b, 0);
|
|
const sumsTo = val => arr => sumArr(arr) === val;
|
|
const zipper = arr => (p, c, i) => arr[i] ? [...p, c, arr[i]] : [...p, c];
|
|
const zip = (a, b) => a.reduce(zipper(b), []);
|
|
const zipArr = arr => a => zip(a, arr);
|
|
const hasInner = v => arr => arr.slice(1, -1).indexOf(v) >= 0;
|
|
const choose = (even, odd) => n => n % 2 === 0 ? even : odd;
|
|
const toBin = f => arr => arr.reduce(
|
|
(p, c, i) => [...p, ...mkArr(c, f(i))], []);
|
|
|
|
|
|
const looper = (arr, max, acc = [[...arr]], idx = 0) => {
|
|
if (idx !== arr.length) {
|
|
const b = looper([...arr], max, acc, idx + 1)[0];
|
|
if (b[idx] !== max) {
|
|
b[idx] = b[idx] + 1;
|
|
acc.push(looper([...b], max, acc, idx)[0]);
|
|
}
|
|
}
|
|
return [arr, acc];
|
|
};
|
|
|
|
const gapPerms = (grpSize, numGaps, minVal = 0) => {
|
|
const maxVal = numGaps - grpSize * minVal + minVal;
|
|
return maxVal <= 0
|
|
? (grpSize === 2 ? [[0]] : [])
|
|
: looper(mkArr(grpSize, minVal), maxVal)[1];
|
|
}
|
|
|
|
const test = (cells, ...blocks) => {
|
|
const grpSize = blocks.length + 1;
|
|
const numGaps = cells - sumArr(blocks);
|
|
|
|
// Filter functions
|
|
const sumsToTrg = sumsTo(numGaps);
|
|
const noInnerZero = compose(inv, hasInner(0));
|
|
|
|
// Output formatting
|
|
const combine = zipArr([...blocks]);
|
|
const choices = toBin(choose(0, 1));
|
|
const output = compose(console.log, arrJoin(''), choices, combine);
|
|
|
|
console.log(`\n${cells} cells. Blocks: ${blocks}`);
|
|
gapPerms(grpSize, numGaps)
|
|
.filter(noInnerZero)
|
|
.filter(sumsToTrg)
|
|
.map(output);
|
|
};
|
|
|
|
test(5, 2, 1);
|
|
test(5);
|
|
test(5, 5);
|
|
test(5, 1, 1, 1);
|
|
test(10, 8);
|
|
test(15, 2, 3, 2, 3);
|
|
test(10, 4, 3);
|
|
test(5, 2, 3);
|