Public
Edited
Oct 28, 2023
6 stars
Insert cell
Insert cell
Insert cell
class Select {
// ((a -> r) -> a) -> Select r a
constructor (selectFn) {
this.fn = selectFn;
}
// a -> f a
static of (x) {
return new Select(() => x);
}

// f a ~> (a -> b) -> f b
map (f) {
return new Select(
R.compose(f, this.fn, R.o(R.__, f))
);
}

// f (a -> b) ~> f a -> f b
ap (s2) {
return new Select(scoreFn => {
const choose = f => runSelect(R.map(f, s2))(scoreFn);
return choose(this.fn(R.o(scoreFn, choose)));
});
}
// m a ~> (a -> m b) -> m b
chain (f) {
return new Select(scoreFn => {
const choose = x => runSelect(f(x))(scoreFn);
return choose(this.fn(R.o(scoreFn, choose)));
});
}
}
Insert cell
Insert cell
Insert cell
Insert cell
epsilon = {
const epsilon = R.curry(
([x, ...xs], p) => xs.length && !p(x) ? epsilon(xs, p) : x
);
return epsilon;
}
Insert cell
Insert cell
Insert cell
{
const digitSelect = new Select(epsilon(R.range(1, 10)));
const sequenceSelect = R.sequence(
Select,
R.repeat(digitSelect, 5)
);
const predicate = seq => R.product(seq) === R.sum(seq) ** 2;
return runSelect(sequenceSelect)(predicate);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
nQueens = {
const candidates = [];
function verifyBoard (board) {
candidates.push(board);
return tails(board).every(
([x, ...xs]) => xs.every(
(y, i) => x !== y && Math.abs(x - y) !== i + 1
)
)
}
// elementSelect :: [a] -> Select Bool a
const elementSelect = domain => new Select(epsilon(domain));
// sequenceSelect :: Eq a => [a] -> Select Bool [a]
const sequenceSelect = domain => new Select(k => {
// return if we're done or if we're on the wrong track
if (!domain.length || !k([])) {
return [];
}

const s = elementSelect(domain).chain(
choice => R.map(
R.prepend(choice),
sequenceSelect(domain.filter(x => x !== choice))
)
);

return runSelect(s)(k);
});
const testFunc = R.memoizeWith(R.identity, verifyBoard);
const solution = runSelect(sequenceSelect(R.range(0, n)))(testFunc);
return { candidates, solution };
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more