Day 6 & 7
This commit is contained in:
134
2024/06/index.ts
Normal file
134
2024/06/index.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8');
|
||||
|
||||
interface Coord { x: number, y: number };
|
||||
enum Dir {
|
||||
Up,
|
||||
Right,
|
||||
Down,
|
||||
Left
|
||||
}
|
||||
|
||||
const obs: Array<Coord> = [];
|
||||
let guard: { pos: Coord, dir: Dir } = { pos: { x: 0, y: 0}, dir: Dir.Up };
|
||||
|
||||
const keyMap: { [key: string]: (pos: Coord) => any } = {
|
||||
"#": (pos: Coord) => obs.push(pos),
|
||||
"^": (pos: Coord) => guard = { pos, dir: Dir.Up },
|
||||
">": (pos: Coord) => guard = { pos, dir: Dir.Up },
|
||||
"v": (pos: Coord) => guard = { pos, dir: Dir.Up },
|
||||
"<": (pos: Coord) => guard = { pos, dir: Dir.Up },
|
||||
}
|
||||
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
for (let i = 0; i <= input.length; i++) {
|
||||
const char = input[i];
|
||||
if (char === "\n") {
|
||||
y++;
|
||||
x = 0;
|
||||
continue;
|
||||
}
|
||||
if (keyMap[char]) {
|
||||
keyMap[char]({ x, y });
|
||||
}
|
||||
x++;
|
||||
}
|
||||
const width = x + 1;
|
||||
const height = y + 1;
|
||||
const guardStart = guard.pos;
|
||||
|
||||
|
||||
const positions: Array<Coord> = [guard.pos];
|
||||
|
||||
function coodsMatch(a: Coord, b: Coord) {
|
||||
return a.x === b.x && a.y === b.y;
|
||||
}
|
||||
|
||||
function getNextPosition() {
|
||||
if (guard.dir === Dir.Up) {
|
||||
return { x: guard.pos.x, y: guard.pos.y - 1 };
|
||||
}
|
||||
if (guard.dir === Dir.Right) {
|
||||
return { x: guard.pos.x + 1, y: guard.pos.y };
|
||||
}
|
||||
if (guard.dir === Dir.Down) {
|
||||
return { x: guard.pos.x, y: guard.pos.y + 1 };
|
||||
}
|
||||
return { x: guard.pos.x - 1, y: guard.pos.y };
|
||||
}
|
||||
|
||||
function rotateGuard() {
|
||||
if (guard.dir === Dir.Up) {
|
||||
guard.dir = Dir.Right;
|
||||
} else if (guard.dir === Dir.Right) {
|
||||
guard.dir = Dir.Down;
|
||||
} else if (guard.dir === Dir.Down) {
|
||||
guard.dir = Dir.Left;
|
||||
} else {
|
||||
guard.dir = Dir.Up;
|
||||
}
|
||||
}
|
||||
|
||||
function isObs(coord: Coord, otherObs: Array<Coord>|null = null) {
|
||||
return (otherObs || obs).some((obsCoord) => coodsMatch(obsCoord, coord));
|
||||
}
|
||||
|
||||
function offMap(coord: Coord) {
|
||||
return coord.x >= width
|
||||
|| coord.x < 0
|
||||
|| coord.y >= height
|
||||
|| coord.y < 0;
|
||||
}
|
||||
|
||||
function alreadyVisited(coord: Coord) {
|
||||
return positions.some((pos) => coodsMatch(pos, coord));
|
||||
}
|
||||
|
||||
while (true) {
|
||||
const nextPos = getNextPosition();
|
||||
if (isObs(nextPos)) {
|
||||
rotateGuard();
|
||||
continue;
|
||||
}
|
||||
if (offMap(nextPos)) {
|
||||
break;
|
||||
}
|
||||
guard.pos = nextPos;
|
||||
if (!alreadyVisited(nextPos)) {
|
||||
positions.push(nextPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Part 2
|
||||
let loops = 0;
|
||||
positions.slice(1).forEach((pos, i) => {
|
||||
console.log(Math.floor(`${i / positions.length * 100}%`));
|
||||
guard.pos = guardStart;
|
||||
guard.dir = Dir.Up;
|
||||
const newObs = [...obs, pos];
|
||||
const guardPositions: Array<string> = [];
|
||||
while (true) {
|
||||
const nextPos = getNextPosition();
|
||||
if (isObs(nextPos, newObs)) {
|
||||
rotateGuard();
|
||||
continue;
|
||||
}
|
||||
if (offMap(nextPos)) {
|
||||
break;
|
||||
}
|
||||
const guardPos = `${guard.pos.x},${guard.pos.y},${guard.dir}`;
|
||||
if (guardPositions.includes(guardPos)) {
|
||||
loops++;
|
||||
break;
|
||||
}
|
||||
guardPositions.push(guardPos);
|
||||
guard.pos = nextPos;
|
||||
}
|
||||
x++;
|
||||
});
|
||||
// End Part 2
|
||||
|
||||
console.log(positions.length);
|
||||
console.log(loops);
|
||||
Reference in New Issue
Block a user