Skip to content

Instantly share code, notes, and snippets.

@martinkadlec0
Last active December 24, 2023 12:58
Show Gist options
  • Select an option

  • Save martinkadlec0/f2b49324ebd5b5859f77f5890127b7d1 to your computer and use it in GitHub Desktop.

Select an option

Save martinkadlec0/f2b49324ebd5b5859f77f5890127b7d1 to your computer and use it in GitHub Desktop.
Advent of Typescript - Day 24 - Santa Maze
type Alley = " ";
type MazeItem = "πŸŽ„" | "πŸŽ…" | Alley;
type Maze = MazeItem[][]
type DELICIOUS_COOKIES = "πŸͺ";
type MazeMatrix = MazeItem[][];
type Directions = "up" | "down" | "left" | "right";
type CoordState = 'win' | 'valid' | 'invalid'
type Inc<N extends number> = [
1,2,3,4,5,6,7,8,9,10,11,
...number[]
][N]
type Dec<N extends number> = [
-1,0,1,2,3,4,5,6,7,8,9,
...number[]
][N]
// Moves santa to new position and replaces last one with Alley (no validation)
type MoveSanta<TMaze extends Maze, RI extends number, CI extends number> = {
[K in keyof TMaze]: TMaze[K] extends infer Row extends MazeItem[] ? {
[J in keyof Row]: Row[J] extends "πŸŽ…"
? Alley
: [K, J] extends [`${RI}`, `${CI}`] ? `πŸŽ…` : Row[J]
} : never
}
// Replaces all cells with a specific item (used for winning cookies)
type FillMaze<TMaze extends Maze, Value extends any> = {
[K in keyof TMaze]: TMaze[K] extends infer Row extends MazeItem[] ? {
[J in keyof Row]: Value
} : never
}
// Finds Cell coordinate of Santa
type FindSantaRow<Row extends MazeItem[], Counter extends number[] = []> =
Row extends [infer Cell, ...infer Rest extends MazeItem[]]
? Cell extends 'πŸŽ…'
? Counter['length']
: FindSantaRow<Rest, [...Counter, 0]>
: 'nope'
// Finds [Row, Cell] coordinates of Santa
type FindSanta<TMaze extends Maze, Counter extends number[] = []> =
TMaze extends [infer Row extends MazeItem[], ...infer Rest extends Maze]
? FindSantaRow<Row> extends infer CI extends number
? [Counter['length'], CI]
: FindSanta<Rest, [...Counter, 0]>
: never
// Takes current Santa's coords and modifies them based on Move
type GetNewCoords<RI extends number, CI extends number, Move extends Directions> =
Move extends 'up'
? [Dec<RI>, CI]
: Move extends 'down'
? [Inc<RI>, CI]
: Move extends 'left'
? [RI, Dec<CI>]
: [RI, Inc<CI>]
// Examines new coordinates and determines if they are valid/invalid or if we got out of maze
type ValidateCoords<TMaze extends Maze, RI extends number, CI extends number> =
RI extends -1 | TMaze['length']
? 'win'
: CI extends -1 | TMaze[0]['length']
? 'win'
: TMaze[RI][CI] extends 'πŸŽ„'
? 'invalid'
: 'valid'
// Main logic: Find Santa Coords -> New coords -> Validate coords -> Move Santa / Win / Hit tree
type Move<TMaze extends Maze, Move extends Directions> =
FindSanta<TMaze> extends [infer RI extends number, infer CI extends number]
? GetNewCoords<RI, CI, Move> extends [infer NewRI extends number, infer NewCI extends number]
? ValidateCoords<TMaze, NewRI, NewCI> extends infer State extends CoordState
? State extends 'valid'
? MoveSanta<TMaze, NewRI, NewCI>
: State extends 'win'
? FillMaze<TMaze, DELICIOUS_COOKIES>
: TMaze
: never
: never
: TMaze
type Test = [
["πŸŽ„", "πŸŽ„", "πŸŽ„", "πŸŽ„", "πŸŽ„", "πŸŽ„"],
["πŸŽ„", " ", " ", " ", "πŸŽ„", "πŸŽ„"],
["πŸŽ„", " ", " ", " ", "πŸŽ…", " "],
["πŸŽ„", "πŸŽ„", "πŸŽ„", "πŸŽ„", " ", "πŸŽ„"],
]
type Res = Move<Test, 'right'>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment