diff --git a/2024/18/index.ts b/2024/18/index.ts new file mode 100644 index 0000000..2b208ba --- /dev/null +++ b/2024/18/index.ts @@ -0,0 +1,148 @@ +const fs = require('fs'); + +const input = fs.readFileSync(__dirname + '/input.txt', 'utf8').split("\n"); + +interface Coord { + x: number, + y: number, +}; + +enum Dir { + Up, + Right, + Down, + Left, +}; + +const map: Array> = []; + +const width = 71; +const height = 71; + +for (let y = 0; y < height; y++) { + if (!map[y]) { + map[y] = []; + } + for (let x = 0; x < width; x++) { + map[y][x] = '.'; + } +} + +for (let i = 0; i < 1024; i++) { + const [x, y] = input[i].split(',').map((st: string) => parseInt(st)); + map[y][x] = '#' +} + +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 printMap() { + const mapClone = map.slice().map((row: Array) => row.slice()); + console.log(mapClone.map((row: Array) => row.join('')).join("\n")); +} + +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 }) + ); +} + +function isDeadEnd(pos: Coord): boolean { + if ((pos.x === 0 && pos.y === 0) || (pos.x === width - 1 && pos.y === width - 1)) { + return false; + } + const adjs = [Dir.Up, Dir.Right, Dir.Down, Dir.Left].map((dir) => get(nextCoord(pos, dir))).join(''); + return adjs === '###.' + || adjs === '##.#' + || adjs === '#.##' + || adjs === '.###'; +} + +function fillDeadEnd(pos: Coord): void { + set(pos, '#') + for (let dir of [Dir.Up, Dir.Right, Dir.Down, Dir.Left]) { + const next = nextCoord(pos, dir); + if (get(next) === '.') { + if (isDeadEnd(next)) { + fillDeadEnd(next); + } + } + }; +} +printMap(); +console.log("\n"); + +for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + const pos = { x, y }; + const char = get(pos); + if (char !== '.') { + continue; + } + if (isDeadEnd(pos)) { + fillDeadEnd(pos); + } + } +} + +printMap(); + +//let fastest: number|null = null; +// +//const scoreCache: { [key: string]: [number, Coord, Dir] } = {}; +// +//const branchCache: { [key: string]: number } = {}; +// +//const scores: Array = []; +// +//function getScoresAfterPosition(pos: Coord, dir: Dir, path: Array = []): void { +// if (fastest !== null && path.length >= fastest) { +// return; +// } +// [dir, nextDir(dir), prevDir(dir)].forEach((newDir, i) => { +// const next = nextCoord(pos, newDir); +// const nextStr = `${next.x},${next.y}`; +// if (!path.includes(nextStr)) { +// if (next.x === width - 1 && next.y === height - 1) { +// if (fastest === null || path.length < fastest) { +// fastest = path.length; +// } +// scores.push(path.length); +// return; +// } else if (next.x >= 0 && next. x < width && next.y >= 0 && next.y < height && get(next) === '.') { +// getScoresAfterPosition(next, newDir, [...path, nextStr]); +// } +// } +// }); +// +// return; +//} +// +//getScoresAfterPosition({ x: 0, y: 0 }, Dir.Up, ['0,0']); +// +//console.log(scores); +//const fastestScore = Math.min(...scores); +//