Files
AoC/2024/20/index.ts
2024-12-20 13:26:37 +00:00

107 lines
2.9 KiB
TypeScript

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 map: Array<Array<string>> = input.split("\n").map((row: string) => row.split(''));
const width = map[0].length;
const height = map.length;
const startIndex = input.indexOf('S');
let startPos = { x: startIndex % (width + 1), y: Math.floor(startIndex / height) };
function get(pos: Coord): string {
if (map[pos.y] && map[pos.y][pos.x]) {
return map[pos.y][pos.x];
}
return '#';
}
function set(pos: Coord, val: string): void {
map[pos.y][pos.x] = val;
}
function nextDir(dir: Dir): Dir {
const directions = [Dir.Up, Dir.Right, Dir.Down, Dir.Left];
const i = (directions.indexOf(dir) + 1) % directions.length;
return directions[i];
}
function prevDir(dir: Dir): Dir {
const directions = [Dir.Up, Dir.Right, Dir.Down, Dir.Left];
const i = directions.indexOf(dir) - 1;
if (i < 0) {
return directions[directions.length - 1];
}
return directions[i];
}
function nextCoord(pos: Coord, direction: Dir): Coord {
return direction === Dir.Up ? { x: pos.x, y: pos.y - 1 }
: (direction === Dir.Right ? { x: pos.x + 1, y: pos.y }
: (direction === Dir.Down ? { x: pos.x, y: pos.y + 1 } : { x: pos.x - 1, y: pos.y })
);
}
const shortCuts: Array<number> = [];
const pathCoords: Array<Coord> = [startPos];
const cheatTime = 20;
const minShortCut = 100;
let speedMap: { [key: string]: number } = {};
function findShortCuts(pos: Coord): void {
for (let i = 0; i < pathCoords.length - minShortCut; i++) {
const possibleSC = pathCoords[i];
const dx = possibleSC.x - pos.x;
const dy = possibleSC.y - pos.y;
const cheatLength = Math.abs(dx) + Math.abs(dy);
if (cheatLength <= cheatTime) {
const shortCutLength = pathCoords.length - i - cheatLength;
if (shortCutLength >= minShortCut) {
shortCuts.push(shortCutLength);
}
}
}
}
for (let dir of [Dir.Up, Dir.Right, Dir.Down, Dir.Left]) {
if (get(nextCoord(startPos, dir)) === '.') {
let pos = startPos;
loop:
while (true) {
for (let newDir of [dir, nextDir(dir), prevDir(dir)]) {
const next = nextCoord(pos, newDir);
const nextStr = `${next.x},${next.y}`;
const nextChar = get(next);
if (nextChar === 'E') {
findShortCuts(next);
pathCoords.push(next);
break loop;
} else if (nextChar === '.') {
findShortCuts(next);
pathCoords.push(next);
pos = next;
dir = newDir;
break;
}
};
}
break;
}
}
console.log(shortCuts.length);