|
|
@ -1,9 +1,4 @@
|
|
|
|
(def input-map
|
|
|
|
(require '[clojure.set])
|
|
|
|
(->> (slurp "./in")
|
|
|
|
|
|
|
|
(clojure.string/split-lines)
|
|
|
|
|
|
|
|
(mapv vec)
|
|
|
|
|
|
|
|
(mapv (partial mapv #(- (int %) 48)))
|
|
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defn get-adj
|
|
|
|
(defn get-adj
|
|
|
|
"Gets vector of coords surrounding (x, y)."
|
|
|
|
"Gets vector of coords surrounding (x, y)."
|
|
|
@ -11,18 +6,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
(defn basin-continues?
|
|
|
|
(defn basin-continues?
|
|
|
|
"Determines if `b` is a continuation of the basin that includes `a`."
|
|
|
|
"Determines if `b` is a continuation of the basin that includes `a`."
|
|
|
|
[a b]
|
|
|
|
[a b] (and (some? b) (not= b 9) (> b a)))
|
|
|
|
(and (some? b) (not= b 9) (> b a)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defn basin-bottom?
|
|
|
|
(defn basin-bottom?
|
|
|
|
"Determines if point `p` in `hmap` is the bottom of a basin surrounded by
|
|
|
|
"Determines if point `p` in `hmap` is the bottom of a basin surrounded by
|
|
|
|
points `adj`."
|
|
|
|
points `adj`."
|
|
|
|
[hmap p adj]
|
|
|
|
[hmap p adj]
|
|
|
|
(empty?
|
|
|
|
(every?
|
|
|
|
(filter
|
|
|
|
#(let [q (get-in hmap %)] (or (nil? q) (< (get-in hmap p) q)))
|
|
|
|
#(let [q (get-in hmap %)] (and (some? q) (> (get-in hmap p) q)))
|
|
|
|
|
|
|
|
adj
|
|
|
|
adj
|
|
|
|
)))
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
(defn find-basin
|
|
|
|
(defn find-basin
|
|
|
|
"If point `yx` in `hmap` is in a basin (determined using `adj`), return a
|
|
|
|
"If point `yx` in `hmap` is in a basin (determined using `adj`), return a
|
|
|
@ -31,21 +24,19 @@
|
|
|
|
(let [res (filter #(basin-continues? (get-in hmap yx)
|
|
|
|
(let [res (filter #(basin-continues? (get-in hmap yx)
|
|
|
|
(get-in hmap %))
|
|
|
|
(get-in hmap %))
|
|
|
|
adj)]
|
|
|
|
adj)]
|
|
|
|
(if-not (empty? res)
|
|
|
|
(apply (partial clojure.set/union res)
|
|
|
|
(apply
|
|
|
|
(map #(set (find-basin hmap % (apply get-adj %))) res)
|
|
|
|
(partial concat res)
|
|
|
|
|
|
|
|
(map
|
|
|
|
|
|
|
|
#(find-basin hmap % (apply get-adj %))
|
|
|
|
|
|
|
|
res
|
|
|
|
|
|
|
|
)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(->> (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?)
|
|
|
|
|
|
|
|
|
|
|
|
(->> (slurp "./in")
|
|
|
|
|
|
|
|
(clojure.string/split-lines)
|
|
|
|
|
|
|
|
(mapv vec)
|
|
|
|
|
|
|
|
(mapv (partial mapv #(- (int %) 48)))
|
|
|
|
|
|
|
|
(#(for [y (range 0 (count %))
|
|
|
|
|
|
|
|
x (range 0 (count (first %)))
|
|
|
|
|
|
|
|
:let [adj (get-adj y x)]
|
|
|
|
|
|
|
|
:when (basin-bottom? % [y x] adj)]
|
|
|
|
|
|
|
|
(inc (count (find-basin % [y x] adj)))))
|
|
|
|
(sort >)
|
|
|
|
(sort >)
|
|
|
|
(take 3)
|
|
|
|
(take 3)
|
|
|
|
(apply *)
|
|
|
|
(apply *)
|
|
|
|