mirror of
https://github.com/seigler/aoc2024
synced 2025-07-27 00:56:10 +00:00
day 16 completed!
This commit is contained in:
parent
1827f39dcb
commit
046e5f9b20
3 changed files with 99 additions and 37 deletions
|
@ -245,10 +245,10 @@
|
||||||
"time": null
|
"time": null
|
||||||
},
|
},
|
||||||
"part2": {
|
"part2": {
|
||||||
"solved": false,
|
"solved": true,
|
||||||
"result": null,
|
"result": "631",
|
||||||
"attempts": [],
|
"attempts": [],
|
||||||
"time": null
|
"time": 132.54635
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
12
README.md
12
README.md
|
@ -26,7 +26,7 @@
|
||||||
[](src/day13)
|
[](src/day13)
|
||||||
[](src/day14)
|
[](src/day14)
|
||||||
[](src/day15)
|
[](src/day15)
|
||||||
[](src/day16)
|
[](src/day16)
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
@ -174,9 +174,9 @@ Both parts: 111802.997ms
|
||||||
|
|
||||||
```
|
```
|
||||||
Day 16
|
Day 16
|
||||||
Time part 1: 88.714ms
|
Time part 1: -
|
||||||
Time part 2: -
|
Time part 2: 132.546ms
|
||||||
Both parts: 88.714ms
|
Both parts: 132.546ms
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -243,8 +243,8 @@ Both parts: -
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
Total stars: 30/50
|
Total stars: 31/50
|
||||||
Total time: 150797.381ms
|
Total time: 150841.213ms
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--/RESULTS-->
|
<!--/RESULTS-->
|
||||||
|
|
|
@ -26,7 +26,6 @@ type Step = {
|
||||||
|
|
||||||
const part1 = (rawInput: string) => {
|
const part1 = (rawInput: string) => {
|
||||||
const input = parseInput(rawInput)
|
const input = parseInput(rawInput)
|
||||||
const get = (r: number, c: number) => (input[r] ?? [])[c]
|
|
||||||
const startIndex = rawInput.indexOf('S')
|
const startIndex = rawInput.indexOf('S')
|
||||||
const c0 = startIndex % (input[0].length + 1)
|
const c0 = startIndex % (input[0].length + 1)
|
||||||
const r0 = (startIndex - c0) / (input[0].length + 1)
|
const r0 = (startIndex - c0) / (input[0].length + 1)
|
||||||
|
@ -42,38 +41,38 @@ const part1 = (rawInput: string) => {
|
||||||
while (pq.size() > 0) {
|
while (pq.size() > 0) {
|
||||||
const prev = pq.pop()
|
const prev = pq.pop()
|
||||||
const { r, c, dir, cost } = prev
|
const { r, c, dir, cost } = prev
|
||||||
const here = get(r, c)
|
const here = input[r][c]
|
||||||
if (here === 'E') {
|
if (here === 'E') {
|
||||||
// draw it
|
{ // draw it
|
||||||
let cur = prev
|
let cur = prev
|
||||||
const visited = new Map<string, number>()
|
const visited = new Map<string, number>()
|
||||||
while (cur.prev.prev !== null) {
|
while (cur.prev.prev !== null) {
|
||||||
visited.set(`${cur.prev.r},${cur.prev.c}`, cur.dir)
|
visited.set(`${cur.prev.r},${cur.prev.c}`, cur.dir)
|
||||||
cur = cur.prev
|
cur = cur.prev
|
||||||
}
|
}
|
||||||
console.log(
|
console.log(
|
||||||
input
|
input
|
||||||
.map((row, r2) => {
|
.map((row, r2) => {
|
||||||
return row
|
return row
|
||||||
.map((cell, c2) => {
|
.map((cell, c2) => {
|
||||||
const key = `${r2},${c2}`
|
const key = `${r2},${c2}`
|
||||||
if (visited.has(key)) return bold(">v<^"[visited.get(key)])
|
if (visited.has(key)) return bold(">v<^"[visited.get(key)])
|
||||||
if (cell === "#") return "\x1b[100m \x1b[0m"
|
if (cell === "#") return "\x1b[100m \x1b[0m"
|
||||||
if (cell === ".") return " "
|
if (cell === ".") return " "
|
||||||
return `\x1b[41m${cell}\x1b[0m`
|
return `\x1b[41m${cell}\x1b[0m`
|
||||||
})
|
})
|
||||||
.join("")
|
.join("")
|
||||||
})
|
})
|
||||||
.join("\n"),
|
.join("\n"),
|
||||||
)
|
)
|
||||||
// done drawing
|
} // done drawing
|
||||||
return cost
|
return cost
|
||||||
}
|
}
|
||||||
for (let i = 0; i < (here === "S" ? 4 : 3); i += 1) {
|
for (let i = 0; i < (here === "S" ? 4 : 3); i += 1) {
|
||||||
const newDir = (dir + 3 + i) % 4 // left, ahead, right, u-turn
|
const newDir = (dir + 3 + i) % 4 // left, ahead, right, u-turn
|
||||||
const [dr, dc] = deltas[newDir]
|
const [dr, dc] = deltas[newDir]
|
||||||
const addedCost = [1001, 1, 1001, 2001][i]
|
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}`
|
const newKey = `${r+dr},${c+dc},${newDir}`
|
||||||
if (pqDict[newKey] !== undefined && pqDict[newKey].cost < cost) continue
|
if (pqDict[newKey] !== undefined && pqDict[newKey].cost < cost) continue
|
||||||
const newStep: Step = {
|
const newStep: Step = {
|
||||||
|
@ -91,8 +90,71 @@ const part1 = (rawInput: string) => {
|
||||||
|
|
||||||
const part2 = (rawInput: string) => {
|
const part2 = (rawInput: string) => {
|
||||||
const input = parseInput(rawInput)
|
const input = parseInput(rawInput)
|
||||||
|
const startIndex = rawInput.indexOf('S')
|
||||||
return
|
const c0 = startIndex % (input[0].length + 1)
|
||||||
|
const r0 = (startIndex - c0) / (input[0].length + 1)
|
||||||
|
const pq = new Heap<Step>((a, b) => a.cost - b.cost)
|
||||||
|
pq.push({
|
||||||
|
r: r0,
|
||||||
|
c: c0,
|
||||||
|
dir: 0,
|
||||||
|
cost: 0,
|
||||||
|
prev: null
|
||||||
|
})
|
||||||
|
const pqDict: Record<string, Step> = {}
|
||||||
|
let bestCost = Number.POSITIVE_INFINITY
|
||||||
|
let visited = new Set<string>([`${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({
|
run({
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue