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> = 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 = []; const pathCoords: Array = [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);