Last active
December 11, 2024 21:45
-
-
Save kirkegaard/e728bf2842997d34981f8af67eb7728a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const input = await Deno.readTextFile("input.txt"); | |
type Position = { x: number; y: number }; | |
type Direction = "up" | "down" | "left" | "right"; | |
type Guard = { | |
position: Position; | |
direction: Direction; | |
}; | |
const DirectionDeltas: Record<Direction, Position> = { | |
up: { x: 0, y: -1 }, | |
down: { x: 0, y: 1 }, | |
left: { x: -1, y: 0 }, | |
right: { x: 1, y: 0 }, | |
}; | |
const DirectionMarkers: Record<Direction, string> = { | |
up: "▲", | |
down: "▼", | |
left: "◄", | |
right: "►", | |
}; | |
function initializeGuard(grid: string[][]): Guard { | |
for (let y = 0; y < grid.length; y++) { | |
for (let x = 0; x < grid[y].length; x++) { | |
if (grid[y][x] === "^") { | |
grid[y][x] = "S"; | |
return { position: { x, y }, direction: "up" }; | |
} | |
} | |
} | |
throw new Error("Guard starting position not found."); | |
} | |
function getNextTile(grid: string[][], guard: Guard): string { | |
const { x, y } = guard.position; | |
const delta = DirectionDeltas[guard.direction]; | |
return grid[y + delta.y]?.[x + delta.x] || ""; | |
} | |
function changeDirection(guard: Guard): void { | |
const directionOrder: Direction[] = ["up", "right", "down", "left"]; | |
const currentIndex = directionOrder.indexOf(guard.direction); | |
guard.direction = directionOrder[(currentIndex + 1) % directionOrder.length]; | |
} | |
function moveGuard(grid: string[][], guard: Guard): void { | |
const { position, direction } = guard; | |
grid[position.y][position.x] = DirectionMarkers[direction]; | |
const delta = DirectionDeltas[direction]; | |
position.x += delta.x; | |
position.y += delta.y; | |
} | |
function markExit(grid: string[][], guard: Guard): void { | |
const { x, y } = guard.position; | |
grid[y][x] = "E"; | |
console.log("Guard is out of the grid", guard.position); | |
} | |
function countVisitedTiles(grid: string[][], markers: Set<string>): number { | |
return grid.flat().filter((tile) => markers.has(tile)).length; | |
} | |
function renderGrid(grid: string[][]): string[] { | |
return grid.map((line) => line.join("")); | |
} | |
const grid = input.split("\n").map((line) => line.split("")); | |
const guard: Guard = initializeGuard(grid); | |
const visitedMarkers = new Set(["▲", "▼", "◄", "►", "S", "E"]); | |
while (true) { | |
const nextTile = getNextTile(grid, guard); | |
if (!nextTile) { | |
markExit(grid, guard); | |
break; | |
} | |
if (nextTile === "#") { | |
changeDirection(guard); | |
} else { | |
moveGuard(grid, guard); | |
} | |
} | |
const theGrid = renderGrid(grid); | |
const visited = countVisitedTiles(grid, visitedMarkers); | |
console.log(theGrid); | |
console.log({ visited }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment