Skip to content

Instantly share code, notes, and snippets.

@kirkegaard
Last active December 11, 2024 21:45
Show Gist options
  • Save kirkegaard/e728bf2842997d34981f8af67eb7728a to your computer and use it in GitHub Desktop.
Save kirkegaard/e728bf2842997d34981f8af67eb7728a to your computer and use it in GitHub Desktop.
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