aoc2024/days/day10.st
2024-12-10 09:58:43 +00:00

56 lines
1.9 KiB
Smalltalk

Object subclass: TrailMap [
| heightMap scores allDirs |
scores [^scores]
initFor: pos [ ^Set new add: pos; yourself ]
initScore [ ^Set new ]
combineScore: score with: other [ score addAll: other. ^score ]
numberFromScore: score [ ^score size ]
initialize [ allDirs := {Posn up. Posn down. Posn left. Posn right}. ]
heights: hm [ heightMap := hm. self initScores. ]
initScores
[ | rows |
rows := (1 to: heightMap height) collect: [
:y | (1 to: heightMap width) collect: [
:x | | pos | pos := Posn x: x y: y.
((heightMap at: pos) = 9)
ifTrue: [self initFor: pos]
ifFalse: [nil]]].
scores := Grid new rows: rows ]
computeScores
[ (8 to: 0 by: -1) do: [:i | self computeScoresForHeight: i]. ]
computeScoresForHeight: h
[ | h1 | h1 := h + 1.
heightMap allPosnsDo: [
:pos |
(heightMap at: pos) = h ifTrue: [
| res | res := self initScore.
allDirs collect: [
:off | | offp | offp := pos + off.
((heightMap at: offp) = h1) ifTrue:
[ res := self combineScore: res with: (scores at: offp) ]].
scores at: pos put: res ]]]
trailheadScores
[ ^(heightMap allPosnsOf: 0) collect: [:p | self numberFromScore: (scores at: p)] ]
]
TrailMap subclass: TrailMapP2 [
initFor: pos [^1]
initScore [^0]
combineScore: score with: other [^score + other]
numberFromScore: score [^score]
]
AOC input: [ | rows |
rows := stdin toLines asArray collect: [
:line | line asArray collect: [:it | it digitValue]].
Grid new rows: rows ];
part1: TrailMap; part2: TrailMapP2;
result: [ :heights :Class | | map |
map := Class new heights: heights.
map computeScores trailheadScores sum ];
finish.