application/octet-stream
•
2.29 KB
•
66 lines
#!/usr/bin/env nujel
[defun is-low-point? [data x y]
[def v [array/2d/ref data x y]]
[def top [if [> y 0]
[array/2d/ref data x [- y 1]]
10]]
[def bottom [if [< y [- [data :height] 1]]
[array/2d/ref data x [+ y 1]]
10]]
[def right [if [< x [- [data :width] 1]]
[array/2d/ref data [+ x 1] y]
10]]
[def left [if [> x 0]
[array/2d/ref data [- x 1] y]
10]]
[and [< v top] [< v bottom] [< v right] [< v left]]]
[defun count-basin-size [data x y]
[if [or [< x 0]
[>= x [data :width]]
[< y 0]
[>= y [data :height]]
[== 9 [array/2d/ref data x y]]]
0
[do [array/2d/set! data x y 9]
[+ 1 [count-basin-size data [- x 1] y]
[count-basin-size data [+ x 1] y]
[count-basin-size data x [- y 1]]
[count-basin-size data x [+ y 1]]]]]]
[defun array/2d/find-low-points [data]
[def low-point-sum 0]
[def basins #nil]
[for [y 0 [data :height]]
[for [x 0 [data :width]]
[when [is-low-point? data x y]
[+= low-point-sum [+ 1 [array/2d/ref data x y]]]
[set! basins [cons [count-basin-size data x y] basins]]]
]]
[def bb [list/sort basins]]
[def biggest-3-basins [list [car bb] [cadr bb] [caddr bb]]]
@[:part1 [low-point-sum] :part2 [apply * biggest-3-basins]]]
[defun map/set/row [data y line w]
[def cols [map [split line ""] int]]
[for [x 0 w]
[array/2d/set! data x y [car cols]]
[cdr! cols]]]
[defun map/load [filename w h]
[def ret [array/2d/allocate w h]]
[def lines [split [file/read filename] "\n"]]
[for [y 0 h]
[map/set/row ret y [car lines] w]
[cdr! lines]]
ret]
[def ex-map [map/load "tests/fast/day9.input" 100 100]]
[def res [array/2d/find-low-points ex-map]]
[def result [res :part1]]
[when [!= result 480]
[throw [list :wrong-result "Wrong result" result]]]
[def result [res :part2]]
[when [!= result 1045660]
[throw [list :wrong-result "Wrong result" result]]]