Day 10
prelude
https://adventofcode.com/2024/day/10
import { grid, inputDay, maybeNumber } from "./lib/utilities.js"
const parser = inp => grid(inp).map(row => row.map(maybeNumber))
const test = parser(`89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732`)
const input = await inputDay(10, { parser })
display(test)
display(input)
// our coördinate system is [row, col], where decreasing y goes up
const N = [-1, 0]
const E = [0, 1]
const S = [1, 0]
const W = [0, -1]
part 1
A function to score a single trailhead
function score(map, trailhead) {
let frontier = [trailhead]
let points = new Set([])
while (frontier.length > 0) {
const [y, x] = frontier.pop()
const val = map[y][x]
if (val == 9) points.add(String([y, x]))
frontier = frontier.concat(
[N, E, S, W]
.map(([dy, dx]) => {
return map[y + dy]?.[x + dx] == val + 1 ? [y + dy, x + dx] : false
})
.filter(Boolean),
)
}
return points.size
}
display(score(test, [0, 2]))
A function to find all trailheads, score them, and sum them
function total(map, score) {
return map
.flatMap((row, y) => row.map((e, x) => (e == 0 ? [y, x] : false)))
.filter(Boolean)
.map(pt => score(map, pt))
.reduce((a, b) => a + b)
}
display(total(test, score))
display(total(input, score))
part 2
for part 2, count the number of times we reach a 9 rather than the number of 9s we reach
function score2(map, trailhead) {
let frontier = [trailhead]
let score = 0
while (frontier.length > 0) {
const [y, x] = frontier.pop()
const val = map[y][x]
if (val == 9) score++
frontier = frontier.concat(
[N, E, S, W]
.map(([dy, dx]) => {
return map[y + dy]?.[x + dx] == val + 1 ? [y + dy, x + dx] : false
})
.filter(Boolean),
)
}
return score
}
display(score2(test, [0, 2]))
We can use the same total score function
display(total(test, score2))
display(total(input, score2))
visualization
for kicks, here's a joy division plot of the map
const chart = Plot.plot({
x: { axis: null },
y: { axis: null },
marks: [
input.map((row, y) =>
Plot.lineY(row, {
x: (_, i) => i,
y: d => d * 2 + y * 10,
curve: "basis",
strokeWidth: 1,
}),
),
],
})
display(chart)