From 046e5f9b2086624def6eecab8a8d9ca602be942f Mon Sep 17 00:00:00 2001 From: Joshua Seigler Date: Tue, 17 Dec 2024 00:26:24 -0500 Subject: [PATCH] day 16 completed! --- .aocrunner.json | 6 +-- README.md | 12 ++--- src/day16/index.ts | 118 ++++++++++++++++++++++++++++++++++----------- 3 files changed, 99 insertions(+), 37 deletions(-) diff --git a/.aocrunner.json b/.aocrunner.json index abea792..5630e4f 100644 --- a/.aocrunner.json +++ b/.aocrunner.json @@ -245,10 +245,10 @@ "time": null }, "part2": { - "solved": false, - "result": null, + "solved": true, + "result": "631", "attempts": [], - "time": null + "time": 132.54635 } }, { diff --git a/README.md b/README.md index 3b24692..893d346 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ [![Day](https://badgen.net/badge/13/%E2%98%85%E2%98%85/green)](src/day13) [![Day](https://badgen.net/badge/14/%E2%98%85%E2%98%86/yellow)](src/day14) [![Day](https://badgen.net/badge/15/%E2%98%85%E2%98%85/green)](src/day15) -[![Day](https://badgen.net/badge/16/%E2%98%85%E2%98%86/yellow)](src/day16) +[![Day](https://badgen.net/badge/16/%E2%98%85%E2%98%85/green)](src/day16) ![Day](https://badgen.net/badge/17/%E2%98%86%E2%98%86/gray) ![Day](https://badgen.net/badge/18/%E2%98%86%E2%98%86/gray) ![Day](https://badgen.net/badge/19/%E2%98%86%E2%98%86/gray) @@ -174,9 +174,9 @@ Both parts: 111802.997ms ``` Day 16 -Time part 1: 88.714ms -Time part 2: - -Both parts: 88.714ms +Time part 1: - +Time part 2: 132.546ms +Both parts: 132.546ms ``` ``` @@ -243,8 +243,8 @@ Both parts: - ``` ``` -Total stars: 30/50 -Total time: 150797.381ms +Total stars: 31/50 +Total time: 150841.213ms ``` diff --git a/src/day16/index.ts b/src/day16/index.ts index 250fa0b..8237c21 100644 --- a/src/day16/index.ts +++ b/src/day16/index.ts @@ -26,7 +26,6 @@ type Step = { const part1 = (rawInput: string) => { const input = parseInput(rawInput) - const get = (r: number, c: number) => (input[r] ?? [])[c] const startIndex = rawInput.indexOf('S') const c0 = startIndex % (input[0].length + 1) const r0 = (startIndex - c0) / (input[0].length + 1) @@ -42,38 +41,38 @@ const part1 = (rawInput: string) => { while (pq.size() > 0) { const prev = pq.pop() const { r, c, dir, cost } = prev - const here = get(r, c) + const here = input[r][c] if (here === 'E') { - // draw it - let cur = prev - const visited = new Map() - while (cur.prev.prev !== null) { - visited.set(`${cur.prev.r},${cur.prev.c}`, cur.dir) - cur = cur.prev - } - console.log( - input - .map((row, r2) => { - return row - .map((cell, c2) => { - const key = `${r2},${c2}` - if (visited.has(key)) return bold(">v<^"[visited.get(key)]) - if (cell === "#") return "\x1b[100m \x1b[0m" - if (cell === ".") return " " - return `\x1b[41m${cell}\x1b[0m` - }) - .join("") - }) - .join("\n"), - ) - // done drawing + { // draw it + let cur = prev + const visited = new Map() + while (cur.prev.prev !== null) { + visited.set(`${cur.prev.r},${cur.prev.c}`, cur.dir) + cur = cur.prev + } + console.log( + input + .map((row, r2) => { + return row + .map((cell, c2) => { + const key = `${r2},${c2}` + if (visited.has(key)) return bold(">v<^"[visited.get(key)]) + if (cell === "#") return "\x1b[100m \x1b[0m" + if (cell === ".") return " " + return `\x1b[41m${cell}\x1b[0m` + }) + .join("") + }) + .join("\n"), + ) + } // done drawing return cost } for (let i = 0; i < (here === "S" ? 4 : 3); i += 1) { const newDir = (dir + 3 + i) % 4 // left, ahead, right, u-turn const [dr, dc] = deltas[newDir] const addedCost = [1001, 1, 1001, 2001][i] - if (get(r + dr, c + dc) === "#") continue + if (input[r + dr][c + dc] === "#") continue const newKey = `${r+dr},${c+dc},${newDir}` if (pqDict[newKey] !== undefined && pqDict[newKey].cost < cost) continue const newStep: Step = { @@ -91,8 +90,71 @@ const part1 = (rawInput: string) => { const part2 = (rawInput: string) => { const input = parseInput(rawInput) - - return + const startIndex = rawInput.indexOf('S') + const c0 = startIndex % (input[0].length + 1) + const r0 = (startIndex - c0) / (input[0].length + 1) + const pq = new Heap((a, b) => a.cost - b.cost) + pq.push({ + r: r0, + c: c0, + dir: 0, + cost: 0, + prev: null + }) + const pqDict: Record = {} + let bestCost = Number.POSITIVE_INFINITY + let visited = new Set([`${r0},${c0}`]) + while (pq.size() > 0) { + const prev = pq.pop() + const { r, c, dir, cost } = prev + const here = input[r][c] + if (here === 'E') { + if (cost > bestCost) break + bestCost = cost + let cursor = prev + visited.add(`${r},${c}`) + while (cursor.prev !== null) { + visited.add(`${cursor.r},${cursor.c}`) + cursor = cursor.prev + } + continue + } + for (let i = 0; i < (here === "S" ? 4 : 3); i += 1) { + const newDir = (dir + 3 + i) % 4 // left, ahead, right, u-turn + const [dr, dc] = deltas[newDir] + const addedCost = [1001, 1, 1001, 2001][i] + if (input[r + dr][c + dc] === "#") continue + const newKey = `${r+dr},${c+dc},${newDir}` + if (pqDict[newKey] !== undefined && pqDict[newKey].cost < cost) continue + const newStep: Step = { + r: r + dr, + c: c + dc, + dir: newDir, + cost: cost + addedCost, + prev, + } + pqDict[newKey] = newStep + pq.push(newStep) + } + } + { // draw it + console.log( + input + .map((row, r2) => { + return row + .map((cell, c2) => { + const key = `${r2},${c2}` + if (visited.has(key)) return bold("O") + if (cell === "#") return "\x1b[100m \x1b[0m" + if (cell === ".") return " " + return `\x1b[41m${cell}\x1b[0m` + }) + .join("") + }) + .join("\n"), + ) + } // done drawing + return visited.size } run({