tangled
alpha
login
or
join now
m1emi1em.dev
/
aoc2025
1
fork
atom
this repo has no description
1
fork
atom
overview
issues
pulls
pipelines
(D4P2): Somewhat optimized rewrite (~6.5s -> ~255ms)
m1emi1em.dev
3 months ago
22b9e92a
0c119de6
+59
-9
1 changed file
expand all
collapse all
unified
split
src
aoc2025
day4.clj
+59
-9
src/aoc2025/day4.clj
···
5
5
(defn- parse-file [fname]
6
6
(->> fname util/read-file util/gridify))
7
7
8
8
+
(def paper? (partial = \@))
9
9
+
8
10
(defn- -get-removable [grid]
9
11
(let [height (-> grid count)
10
12
width (-> grid first count)
···
25
27
; Laziest optimization in existence but it makes part2 run in 6.5s instead of like 19s so yay
26
28
(def get-removable (memoize -get-removable))
27
29
28
28
-
(defn- part1 [grid]
29
29
-
(-> grid get-removable count))
30
30
-
31
31
-
(defn- remove-paper [grid] (reduce #(assoc-in %1 %2 \.) grid (get-removable grid)))
30
30
+
(defn- valid-adj [[y x :as pos] width height]
31
31
+
(letfn [(valid-coord? [[cy cx]]
32
32
+
(and (util/between? cy -1 height >)
33
33
+
(util/between? cx -1 width >)))]
34
34
+
(->> pos util/adj+
35
35
+
(filter valid-coord?))))
32
36
33
37
(defn- part2 [grid]
34
34
-
(->> grid
35
35
-
(iterate remove-paper)
36
36
-
(take-while #(> (-> % get-removable count) 0))
37
37
-
(map (comp count get-removable))
38
38
-
(reduce +)))
38
38
+
(let [grid-height (-> grid count)
39
39
+
grid-width (-> grid first count)
40
40
+
41
41
+
#_(First thing is to get a list of only the spots with paper on them)
42
42
+
all-paper-spots
43
43
+
(set
44
44
+
(for [idy (range grid-height)
45
45
+
idx (range grid-width)
46
46
+
:let [pos [idy idx]]
47
47
+
:when (paper? (get-in grid pos))]
48
48
+
pos))
49
49
+
50
50
+
#_(For each paper spot, find all adjacent spots. Make a map of format {position [adjacent spots with paper]})
51
51
+
paper-spots-to-adjacent-paper-spots
52
52
+
(into {}
53
53
+
(for [pos all-paper-spots
54
54
+
:let [adjacents (->> (valid-adj pos grid-width grid-height)
55
55
+
(filter all-paper-spots))]]
56
56
+
[pos adjacents]))
57
57
+
58
58
+
59
59
+
removable? (fn [[_ v]] (-> v count (< 4)))
60
60
+
any-removable? (fn [m] (some (fn [[_ v]] (removable? [nil v])) m))
61
61
+
62
62
+
#_(Deletes a paper spot and any references to it by its neighbors)
63
63
+
remove-a-paper
64
64
+
(fn [paper-spots [spot neighbors]]
65
65
+
(-> (reduce #(update %1 %2 (partial remove #{spot})) paper-spots neighbors)
66
66
+
(dissoc spot)))
67
67
+
68
68
+
#_(Takes the current paper spots and returns a list of paper spots with all paper currently eligible to be remove removed)
69
69
+
paper-iterator
70
70
+
(fn [paper-spots]
71
71
+
(let [to-remove (filter removable? paper-spots)]
72
72
+
(reduce remove-a-paper paper-spots to-remove)))
73
73
+
74
74
+
starting-paper-count (count all-paper-spots)
75
75
+
76
76
+
final-state
77
77
+
(->> paper-spots-to-adjacent-paper-spots
78
78
+
(iterate paper-iterator)
79
79
+
(split-with any-removable?)
80
80
+
second
81
81
+
first)
82
82
+
83
83
+
final-paper-count (-> final-state keys count)]
84
84
+
(- starting-paper-count final-paper-count)))
85
85
+
86
86
+
(defn- part1 [grid]
87
87
+
(-> grid get-removable count))
39
88
40
89
(defn solve
41
90
([] (solve "04.txt"))
···
43
92
(->> (parse-file fname) ((juxt part1 part2)))))
44
93
45
94
(solve "04-test.txt") ; [13 43]
95
95
+