-
Notifications
You must be signed in to change notification settings - Fork 0
/
core.clj
108 lines (95 loc) · 2.75 KB
/
core.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
(ns _2021.nine.core
(:require [util :refer [input]]
[clojure.set :as set]))
(defn parse [f]
(->> f
input
(map #(->> (re-seq #"\d" %) (map read-string) vec))
vec))
(comment
(parse "example.txt")
(input "input.txt")
)
(defn num-at [rows x y]
(when-let [row (nth rows y nil)]
(when-let [num (nth row x nil)]
num)))
(defn neighbors [rows x y]
(->>
[(num-at rows x (inc y))
(num-at rows (dec x) y)
(num-at rows (inc x) y)
(num-at rows x (dec y))]
(remove nil?)))
(defn is-low-point [rows x y]
(let [nbrs (neighbors rows x y)
this (num-at rows x y)
this-is-lowest? (->> nbrs
(map #(or (not %) (< this %)))
(every? true?))]
(when this-is-lowest? this)))
(defn collect-low-points [f]
(let [rows (parse f)
y (count rows)
x (count (first rows))
low-points (atom [])]
(doall
(for [i (range x)
j (range y)]
(when-let [num (is-low-point rows i j)]
(swap! low-points conj num))))
@low-points))
(comment
(->> (collect-low-points "input.txt")
(map inc)
(apply +)
)
)
(defn collect-low-positions [f]
(let [rows (parse f)
y (count rows)
x (count (first rows))
low-poses (atom [])]
(doall
(for [i (range x)
j (range y)]
(when-let [num (is-low-point rows i j)]
(swap! low-poses conj {:num num :x i :y j}))))
{:low-positions @low-poses
:rows rows}))
(defn valid-neighbor-positions [rows x y]
(->>
[{:x x :y (inc y)}
{:x x :y (dec y)}
{:x (inc x) :y y}
{:x (dec x) :y y}]
(filter (fn [{:keys [x y]}] (num-at rows x y)))))
(defn collect-neighbors [rows x y]
(loop [to-check #{{:x x :y y}}
collected #{{:x x :y y}}]
(if-not (seq to-check)
collected
(let [next (first to-check)
rst (->> (rest to-check) (into #{}))
new-nbrs (->> (valid-neighbor-positions rows (:x next) (:y next))
(remove (comp #{9} (fn [{:keys [x y]}]
(num-at rows x y))))
(remove collected)
(into #{}))]
(recur
(set/union new-nbrs rst)
(set/union new-nbrs collected))))))
(defn ->basin-size [rows {:keys [x y]}]
(let [neighbors (collect-neighbors rows x y)]
(count neighbors))
)
(comment
(let [{:keys [low-positions rows]} (collect-low-positions "example.txt")]
(->> low-positions
(map (partial ->basin-size rows))
sort
reverse
(take 3)
(apply *))
)
)