diff --git a/src/06/help.js b/src/06/help.js new file mode 100644 index 0000000..82f8748 --- /dev/null +++ b/src/06/help.js @@ -0,0 +1,124 @@ +Object.defineProperties(Array.prototype, { + sum: { + value: function () { + return this.map(Number).reduce((p, a) => p + a, 0); + }, + }, + sortf: { + value: function () { + return this.sort((a, b) => a - b); + }, + }, + prod: { + value: function () { + return this.map(Number).reduce((p, a) => p * a, 1); + }, + }, + rotate: { + value: function (n) { + n = n % this.length; + while (this.length && n < 0) n += this.length; + this.push.apply(this, this.splice(0, n)); + return this; + }, + }, + firstn: { + value: function (n) { + return n >= 0 ? this.sort((a, b) => b - a).slice(0, n) : []; + }, + }, + occur: { + value: function () { + return this.reduce((acc, curr) => { + acc[curr] = acc[curr] + 1 || 1; + return acc; + }, {}); + }, + }, +}); +Number.prototype.mod = function (n) { + return ((this % n) + n) % n; +}; + +const input = require("fs") + .readFileSync(`${String(__dirname).replace(/\\/g, "/")}/input.txt`, "utf8") + .replace(/\r/g, ""); + +const dirs = [ + [-1, 0], + [0, 1], + [1, 0], + [0, -1], +]; +const grid = input.split("\n").map((e) => e.split("")); +let startpos = [-1, -1]; +let startdir = 0; +for (let i = 0; i < grid.length; i++) { + for (let j = 0; j < grid[i].length; j++) { + if (grid[i][j] == "^") { + startpos = [i, j]; + grid[i][j] = "."; + break; + } + } + if (startpos[0] !== -1) break; +} +let pos = [...startpos]; +let dir = startdir; + +visited = new Set(); +visited.add(`${pos[0]},${pos[1]}`); +const turnRight = (d) => { + return (d + 1) % 4; +}; +const ingrid = (row, col) => + row >= 0 && row < grid.length && col >= 0 && col < grid[0].length; + +while (true) { + let nextpos = [pos[0] + dirs[dir][0], pos[1] + dirs[dir][1]]; + if (!ingrid(nextpos[0], nextpos[1])) { + break; + } + if (grid[nextpos[0]][nextpos[1]] === "#") { + dir++; + dir %= 4; + } else { + pos = [nextpos[0], nextpos[1]]; + visited.add(`${pos[0]},${pos[1]}`); + } +} + +console.log(visited.size); + +let loops = (obs) => { + let temp = grid.map((e) => e.map((e) => e)); + temp[obs[0]][obs[1]] = "#"; + let pos = [...startpos]; + let dir = startdir; + let visited = new Set(); + while (true) { + let state = `${pos[0]},${pos[1]},${dirs[dir][0]},${dirs[dir][1]}`; + if (visited.has(state)) return true; + visited.add(state); + let nextpos = [pos[0] + dirs[dir][0], pos[1] + dirs[dir][1]]; + if (!ingrid(nextpos[0], nextpos[1])) return false; + if (temp[nextpos[0]][nextpos[1]] == "#") { + dir++; + dir %= 4; + } else { + pos = [nextpos[0], nextpos[1]]; + } + } +}; +let loopPositions = 0; +for (let i = 0; i < grid.length; i++) { + for (let j = 0; j < grid[0].length; j++) { + if (!visited.has(`${i},${j}`)) continue; + if (grid[i][j] == "#") continue; + if (i == startpos[0] && j == startpos[1]) continue; + if (loops([i, j])) { + loopPositions++; + } + } +} +console.log(loopPositions); //2.116s :( diff --git a/src/06/input.txt b/src/06/input.txt new file mode 100644 index 0000000..f4dd47a --- /dev/null +++ b/src/06/input.txt @@ -0,0 +1,130 @@ +.....#..#................#...#.....#.......................................................#.............................##....... +......................#..............................................................#..............#..........................#.. +.........#........................#.....................................................#..............#...........#........##.... +..........#......................#.....#...#............#..........................#.....#........................................ +#....................................................................................................................#............ +.#....#......................#.......................#...............................#...#.....#...................#........#..... +..#..#.......................##........#...............................................................#........#.........#....... +..............................................................#...#.........#..#.................................................. +.............####..................................#................#..#.....................................#.....#.............. +..........#................#................................................#........................#.....#...................... +..............................................#.........#.....................#..................#.......................#........ +.........................................##..#.................................#.....#............................................ +............#..#...#...............................#.#.....#...............#...............................#..............#.#.#..# +.................#..........#..#....#.....................#......................................##............#.................. +.......#....#.....................#......##...................#..............#.................#........#..#......#............... +...............................................#.............#.................................................................... +..............#..............................................##..................#..........................#............#........ +................#.......................#..#............................................................#..........#..#.........#. +.#.......................###............#.........#.................................................#............................. +........#......................................................................................#.....#.......#...#................ +#.#.........................#..#.............................................#....#........................#...................... +.......#.....#...............................#.....#......................#.................................#.....#...#........... +................................................................................................#............#.................... +.......#......#...............#...#............................#................................#................................# +.#.....................................................................................................................#......#... +...........#..........................................#........#...................#.............................................. +....#......................................................................................#.....##.#...................#......... +...#..........................................................................##.......................................#.....#.... +#........#................#...............#.........#..#.#..............##..............#........#............#....#.....#........ +......#......................................#...............#....#..#...........................#................................ +#..............................................................................#............#...#..#....................#......#.. +.......#.........................................#.........#.......#....................................#......................... +......#......#.............................................#.....................#...........#.............#..#................... +#.......................#........#............................................##..............................#................... +..........................................................................#........................................#....#......#.. +..........#..#...............................................#............................#.#..............................#...... +....#...........#..#...................................#................................................................#......... +..............#..........#...............#....#.....................................#.......................#..................... +.............#........#....#.........#...............#.........#.................................................................. +.#......#...................#.......#...........................................................................#.............#... +.............##...........#.........................................#......................#.......................#.............. +.....#................#.....#...................##.......#......#...........#.......#............................................# +.#..#.............................................................#..............................................#................ +...#......#............................#.......................................................................................... +...................................................................................#.............................................. +#...................................#...................##..................#...............................................#..... +................#.....#...........................#............................................................................... +.................................#............#........................................................#.............#............ +..................#......#........................................................#..^.....#...................................... +..#.....#.................................................#........#.........................................................#..#. +................#..............................#....................................................#............................. +................#....#..........................................#............................#.................................... +...............#.......................................#.....................................#..............................#..... +..................................................#............#..............#........##.#.....................................#. +.#..................................#......#..#............#.................#.............#......#..#.......................#.... +..................#..............................#..........................#..........................##............#.......#.... +.........#..................................................................#...................#..........................#...... +................#....................................#............#............................................................#.. +..##..........#.#..#........................#....#.................................#.............................................# +............................................#.........................................................#..#...................#...# +.......................................#......................................................................#................... +....#.......................#...#.........................................................................#................#...... +...........#...........#............#.....#...#...................#........................................#.................##... +....#...........................................................................................#................................. +..............................................................................#.#.............................................#... +.........#..#..............................................#...................................................................... +#...................#........#............#.......#.....................#................#.#.#............#..................#.... +.......................#................#.....#...........#.....................#...........................#..........#.........# +........................................................................#.#.....................#................................. +...#.................................................#..........................#........#.......................#................ +............................#...........#.......#.................................#.##...........#............................#... +...##.....................................#.........................#...........#...................................#............. +#.#..#................................#.........#..#.#..........#......................#............#......................#...... +....#.............................................................#............................................................... +...............#.#......#........................................................................#.........................#...... +................#.....#...#...............#.........................................#....#...........................#.......#.... +...............#.........................................................................#........................................ +..........................#..##................................................................................................... +.##....................#..#.....................#..............................................#........................#......... +............................................................................................#............#........................ +#...................#...#......................#...............#............#....................................#................ +...........................#........#......................................................................#...................... +................................#...#...#.#.......#.................#.......#................##................................... +........................#.......................#................................................................................. +#...#...............#.........................................................................#.......................#........... +.........#...................#...............................................#...................##..............................# +.....#............................................................................................................................ +.#.......#...............................................................#.......................#................#..........#.... +....................................#..........#......#...........................................................#.#.#..#...#.... +......................#..............................................##..................#........................................ +....#......#...................#................#..............................................................................#.. +...........#.................##.#...................................................#..#................#......................... +......#.....#......#...#........#.....................................#....#...........#................#..........#.............. +#.......##.....#........#...........................................#...#..........#.............#........#.......#............... +......................#......#...................#.........................#........................#..................#...#...... +.....#...........#...#.........................##.......#.....................................#................................... +....................................................................#............................................................. +........#...............#......................................................................................................... +.......................#.........................#..........................................#.#....#..#....#...................... +........................##............................................................#.....#.........#....#......#..#............ +........................#........#..................#................#.#.##............#.......................................... +.......................................................#.........................#...............##...................##....#...#. +........#...#.............#...........#........#......................#...#.........#..#..................#.#............#........ +#.#....................#..........................................#...................................................#........#.. +...............................................#............#.....#.#...........#........#.#....................................#. +......#..........................................#............................................................#..........#...#...# +....................#......................................#....#..............................#....................#............. +......................#.#.....#......#....#..#.................................................................................... +.....#..........................................#.........#...................................#................#.......#.......... +........##....................................................................#...................................#.............#. +#.........................................#..#....#................#.#.....#....................#............................#.... +#....#..#..........#..................#......................#.................................................................... +...................#..#....#...................#...........................#.#..#............#......#................#.......#.#.. +...............#......................................................#......#..#..............#.....................#............ +............#.....................#.........#....#...............#.......#...#...............#.......................##.#......... +....#............#..................#....#.......................#..............................................#...#............. +..........................................#....#..........#..#....................#......#......................#...#............. +............#..........#...........#......#..#......................................................................#............. +...#.................#.............................................................#.............................................. +.....#.#.........#....................................................#..................#...............#........................ +..#......................##.....#.........#..............#..#............#..#............................................#........ +...................#.....#.........#........#....................#..................................#................#............ +....#.............................#.............................#.......................#.......................#.....#........... +...#......#....#...........#............................#.....#........#......#................................................... +........#..........#............................#..#..#.......................................#....#.##........................... +.......#......##........#.................#.............................................................#....#........#........... +.....................#............................................#.#......#.....##....#........#................................. +...........#.....................##.#....#..#..................................................................................... +....................#......#................................#.....................................................#.......#..#.... +.....................................................#.........#.......................................#.....##..#................ diff --git a/src/06/main.ts b/src/06/main.ts new file mode 100644 index 0000000..7415ba8 --- /dev/null +++ b/src/06/main.ts @@ -0,0 +1,118 @@ +// { positionCount: 5312, loopCount: 1748 } + +type Direction = "y" | "-y" | "x" | "-x"; + +const rotateRight: Record = { + "-y": "x", + "x": "y", + "y": "-x", + "-x": "-y", +}; + +type Position = [y: number, x: number, next: Direction]; + +type Map = string[][]; + +function getNextPosition(p: Position): Position { + switch (p[2]) { + case "y": + return [p[0] + 1, p[1], p[2]]; + case "-y": + return [p[0] - 1, p[1], p[2]]; + case "x": + return [p[0], p[1] + 1, p[2]]; + case "-x": + return [p[0], p[1] - 1, p[2]]; + } +} + +export async function main(target = "input") { + const dirpath = new URL(".", import.meta.url).pathname; + const text = await Deno.readTextFile(`${dirpath}${target}.txt`); + + const { map, start } = text.split("\n").reduce< + { map: Map; start: Position } + >( + (agg, line, idx) => { + if (line.match(/^[.#^]+$/)) { + const chars = line.split(""); + const startX = chars.findIndex((char) => char === "^"); + if (startX !== -1) { + chars[startX] = "."; + agg.start = [idx, startX, "-y"]; + } + agg.map.push(chars); + } + return agg; + }, + { map: [], start: [0, 0, "y"] }, + ); + + let guard = start; + let positionCount = 0; + const positionHistory = []; + + while ( + guard[0] >= 0 && + guard[0] < map.length && guard[1] >= 0 && guard[1] < map[0].length + ) { + let next = getNextPosition(guard); + while (map[next[0]]?.[next[1]] === "#") { + guard[2] = rotateRight[guard[2]]; + next = getNextPosition(guard); + } + + if (map[guard[0]][guard[1]] === ".") { + map[guard[0]][guard[1]] = "X"; + positionCount++; + } + positionHistory.push(guard); + guard = next; + } + + const loopCount = positionHistory.reduce((agg, position) => { + const obstruction = getNextPosition(position); + if ( + obstruction[0] < 0 || + obstruction[0] >= map.length || obstruction[1] < 0 || + obstruction[1] >= map[0].length || + map[obstruction[0]][obstruction[1]] === "O" + ) { + return agg; + } + + const collisionSet = new Set(); + let guard: Position = [...start]; + let guardKey = ""; + + while ( + guard[0] >= 0 && + guard[0] < map.length && guard[1] >= 0 && guard[1] < map[0].length + ) { + let next = getNextPosition(guard); + while ( + map[next[0]]?.[next[1]] === "#" || + next[0] === obstruction[0] && next[1] === obstruction[1] + ) { + guardKey = guard.toString(); + if ( + collisionSet.has(guardKey) + ) { + map[obstruction[0]][obstruction[1]] = "O"; + return agg + 1; + } + collisionSet.add(guardKey); + guard[2] = rotateRight[guard[2]]; + next = getNextPosition(guard); + } + guard = next; + } + return agg; + }, 0); + + return { positionCount, loopCount }; +} + +if (import.meta.main) { + console.log(await main()); +} diff --git a/src/06/sample.txt b/src/06/sample.txt new file mode 100644 index 0000000..a4eb402 --- /dev/null +++ b/src/06/sample.txt @@ -0,0 +1,10 @@ +....#..... +.........# +.......... +..#....... +.......#.. +.......... +.#..^..... +........#. +#......... +......#... diff --git a/src/06/test.ts b/src/06/test.ts new file mode 100644 index 0000000..949b288 --- /dev/null +++ b/src/06/test.ts @@ -0,0 +1,12 @@ +import { assertEquals } from "@std/assert"; +import { main } from "./main.ts"; + +Deno.test("correct position count for sample", async () => { + const result = await main("sample"); + assertEquals(result.positionCount, 41); +}); + +Deno.test("correct loop count for sample", async () => { + const result = await main("sample"); + assertEquals(result.loopCount, 6); +});