application/octet-stream
•
2.40 KB
•
70 lines
#!/usr/bin/env nujel
(require :array/2d)
(defn 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 (- (ref data :height) 1))
(array/2d/ref data x (+ y 1))
10))
(def right (if (< x (- (ref 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)))
(defn count-basin-size (data x y)
(if (or (< x 0)
(>= x (ref data :width))
(< y 0)
(>= y (ref 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))))))
(defn array/2d/find-low-points (data)
(def low-point-sum 0)
(def basins #nil)
(dotimes (y (ref data :height))
(dotimes (x (ref 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 (reverse (sort basins)))
(def biggest-3-basins (list (car bb) (cadr bb) (caddr bb)))
{:part1 low-point-sum :part2 (* (car bb) (cadr bb) (caddr bb))})
(defn map/set/row (data y line w)
(def cols (map (split line "") read/int))
(dotimes (x w)
(array/2d/set! data x y (car cols))
(cdr! cols)))
(defn map/load (filename w h)
(def ret (array/2d/allocate w h))
(def lines (split (file/read filename) "\n"))
(dotimes (y h)
(map/set/row ret y (car lines) w)
(cdr! lines))
ret)
(def ex-map (map/load "tests/slow/day9.dat" 100 100))
(def res (array/2d/find-low-points ex-map))
(def result (ref res :part1))
(when (not= result 480)
(throw (list :wrong-result "Wrong result" result)))
(def result (ref res :part2))
(when (not= result 1045660)
(throw (list :wrong-result "Wrong result" result)))
(return :success)