Nim
As many others today, I've solved part 2 first and then fixed a 'bug' to solve part 1. =)
type Vec2 = tuple[x,y:int]
const Adjacent = [(x:1,y:0),(-1,0),(0,1),(0,-1)]
proc path(start: Vec2, grid: seq[string]): tuple[ends, trails: int] =
var queue = @[@[start]]
var endNodes: HashSet[Vec2]
while queue.len > 0:
let path = queue.pop()
let head = path[^1]
let c = grid[head.y][head.x]
if c == '9':
inc result.trails
endNodes.incl head
continue
for d in Adjacent:
let nd = (x:head.x + d.x, y:head.y + d.y)
if nd.x < 0 or nd.y < 0 or nd.x > grid[0].high or nd.y > grid.high:
continue
if grid[nd.y][nd.x].ord - c.ord != 1: continue
queue.add path & nd
result.ends = endNodes.len
proc solve(input: string): AOCSolution[int, int] =
let grid = input.splitLines()
var trailstarts: seq[Vec2]
for y, line in grid:
for x, c in line:
if c == '0':
trailstarts.add (x,y)
for start in trailstarts:
let (ends, trails) = start.path(grid)
result.part1 += ends
result.part2 += trails
Nim
Runtime: 30-40 ms
I'm not very experienced with recursion and memoization, so this took me quite a while.
Edit: slightly better version
Codeberg repo