Skip to content

Instantly share code, notes, and snippets.

@dra1n
Last active December 17, 2024 11:00
Show Gist options
  • Save dra1n/2b2610f6cfe46c8784488019ff3bce63 to your computer and use it in GitHub Desktop.
Save dra1n/2b2610f6cfe46c8784488019ff3bce63 to your computer and use it in GitHub Desktop.
const range = (start: number, end: number) =>
Array.from({ length: end - start + 1 }, (v, k) => k + start);
/* Monad */
const ret = <T>(x: T): T[] => [x];
const bind = <T>(xs: T[], f: (v: T) => T[]): T[] => xs.map(f).flat();
const fail = <T>(_: T): T[] => [];
/* Knight problem */
type KnightPos = [number, number];
const moveKnight = (pos: KnightPos): KnightPos[] =>
bind(ret(pos), ([c, r]: KnightPos): KnightPos[] => [
[c + 2, r - 1],
[c + 2, r + 1],
[c - 2, r - 1],
[c - 2, r + 1],
[c + 1, r - 2],
[c + 1, r + 2],
[c - 1, r - 2],
[c - 1, r + 2],
]).filter(
([c, r]: KnightPos) => range(1, 8).includes(c) && range(1, 8).includes(r)
);
const in3 = (start: KnightPos): KnightPos[] =>
[1, 2, 3].reduce((result) => bind(result, moveKnight), ret(start));
const canReachIn3 = (start: KnightPos, [c, r]: KnightPos): boolean =>
in3(start).some(([sc, sr]) => sc == c && sr == r);
console.log(canReachIn3([6, 2], [6, 1])); // true
console.log(canReachIn3([6, 2], [7, 3])); // false