diff --git a/day9/part2.clj b/day9/part2.clj index 455cb39..dd05b7d 100644 --- a/day9/part2.clj +++ b/day9/part2.clj @@ -5,60 +5,50 @@ (mapv (partial mapv #(- (int %) 48))) )) -(defn basin-bottom-single? [a b] - (if (or (nil? a) (nil? b) (< a b)) 1 0)) +(defn get-adj + "Gets vector of coords surrounding (x, y)." + [y x] [[(dec y) x] [(inc y) x] [y (dec x)] [y (inc x)]]) -(defn basin-continues? [a b] +(defn basin-continues? + "Determines if `b` is a continuation of the basin that includes `a`." + [a b] (and (some? b) (not= b 9) (> b a))) -(defn basin-bottom? [hmap p adj] - (= 4 - (apply + - (map - #(basin-bottom-single? - (get-in hmap p) - (get-in hmap %)) - adj - )))) +(defn basin-bottom? + "Determines if point `p` in `hmap` is the bottom of a basin surrounded by + points `adj`." + [hmap p adj] + (empty? + (filter + #(let [q (get-in hmap %)] (and (some? q) (> (get-in hmap p) q))) + adj + ))) -(defn get-adj [y x] - [[(dec y) x] - [(inc y) x] - [y (dec x)] - [y (inc x)]]) - -(defn find-basin [hmap y x adj] - (let [res (reduce - #(if - (basin-continues? (get-in hmap [y x]) - (get-in hmap %2)) - (conj %1 %2) - %1) - [] - adj - )] - (if (empty? res) - [] +(defn find-basin + "If point `yx` in `hmap` is in a basin (determined using `adj`), return a + list of points in the basin that are above `yx`." + [hmap yx adj] + (let [res (filter #(basin-continues? (get-in hmap yx) + (get-in hmap %)) + adj)] + (if-not (empty? res) (apply (partial concat res) (map - #(find-basin hmap (first %) (second %) (apply get-adj %)) - res)) - ) - ) - ) + #(find-basin hmap % (apply get-adj %)) + res + ))))) -(println - (apply * - (take 3 - (sort > - (filter - pos? - (for [y (range 0 (count input-map)) - x (range 0 (count (first input-map)))] - (let [adj (get-adj y x)] - (if (basin-bottom? input-map [y x] adj) - (count (distinct (concat [[y x]] (find-basin input-map y x adj)))) - 0 - )))))))) +(->> (for [y (range 0 (count input-map)) + x (range 0 (count (first input-map)))] + (let [adj (get-adj y x)] + (when (basin-bottom? input-map [y x] adj) + (inc (count (distinct (find-basin input-map [y x] adj)))) + ))) + (filter some?) + (sort >) + (take 3) + (apply *) + (println) + )