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
@dra1n
Copy link
Author

dra1n commented Jul 16, 2024

moveKnight :: KnightPos –> [KnightPos]
moveKnight (c,r) = do
 (c',r') <– [(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)
              ]
   guard (c' `elem` [1..8] && r' `elem` [1..8])
   return (c',r')

in3 :: KnightPos –> [KnightPos]
in3 start = do
   first <– moveKnight start
   second <– moveKnight first
   moveKnight second

-- or

in3 start = return start >>= moveKnight >>= moveKnight >>= moveKnight

canReachIn3 :: KnightPos –> KnightPos –> Bool
canReachIn3 :: KnightPos –> KnightPos –> Bool canReachIn3 start end = end `elem` in3 start

(6, 2) `canReachIn3` (6, 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment