Skip to content

Commit a046843

Browse files
committed
2024, day 15
1 parent 77a0093 commit a046843

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

2024/15.clj

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
(require '[clojure.string :as str]
2+
'[clojure.set :as set])
3+
4+
(def lines (str/split-lines (slurp "2024/15.sample2.in")))
5+
(def the-map (pop (pop lines)))
6+
(def moves (peek lines))
7+
8+
(def pos->entity
9+
(into {}
10+
(for [i (range (count the-map))
11+
j (range (count (first the-map)))
12+
:let [entity (get-in the-map [i j])]
13+
:when (#{\# \@ \O} entity)]
14+
(if (= entity \@) (do (def initial-position [i j]) nil)
15+
[[i j] entity]))))
16+
17+
(def direction->delta {\< [0 -1], \> [0 1], \^ [-1 0], \v [1 0]})
18+
(defn p+ [p1 p2] (mapv + p1 p2))
19+
20+
(defn debug [[position pos->entity]]
21+
(doseq [i (range (count the-map))
22+
j (range (count (first the-map)))]
23+
(when (= j 0) (println))
24+
(if (= [i j] position)
25+
(print \@)
26+
(print (or (get pos->entity [i j]) ".")))))
27+
28+
(defn move-and-push [[position pos->entity] direction]
29+
;; (debug [position pos->entity])
30+
(let [delta (direction->delta direction)]
31+
(loop [looking-at (p+ position delta), seen-box false]
32+
(case (get pos->entity looking-at)
33+
\O (recur (p+ looking-at delta) true)
34+
\# [position pos->entity]
35+
[(p+ position delta)
36+
(if seen-box
37+
(-> pos->entity
38+
(dissoc (p+ position delta))
39+
(assoc looking-at \O))
40+
pos->entity)]))))
41+
42+
(defn gps-sum [[_ pos->entity]]
43+
(reduce + (keep (fn [[[i j] c]] (when (= c \O) (+ (* 100 i) j))) pos->entity)))
44+
45+
(gps-sum (reduce move-and-push [initial-position pos->entity] moves))
46+
47+
(defn box-at [boxes [i j]] (or (boxes [i j]) (boxes [i (dec j)])))
48+
49+
(let [*walls (transient #{}), *boxes (transient #{})]
50+
(doseq [i (range (count the-map))
51+
j (range (count (first the-map)))
52+
:let [entity (get-in the-map [i j])]
53+
:when (#{\# \@ \O} entity)]
54+
(case entity
55+
\O (conj! *boxes [i (* j 2)])
56+
\# (-> *walls
57+
(conj! [i (* j 2)])
58+
(conj! [i (inc (* j 2))]))
59+
\@ (def initial-position [i (* j 2)])))
60+
(def walls (persistent! *walls))
61+
(def boxes (persistent! *boxes)))
62+
63+
(defn debug' [[position boxes]]
64+
(doseq [i (range (count the-map))
65+
j (range (* (count (first the-map)) 2))]
66+
(when (= j 0) (println))
67+
(cond
68+
(= [i j] (box-at boxes [i j]))
69+
(print \[)
70+
71+
(= [i (dec j)] (box-at boxes [i j]))
72+
(print \])
73+
74+
(walls [i j])
75+
(print "#")
76+
77+
(= [i j] position)
78+
(print "@")
79+
80+
:else
81+
(print " "))))
82+
83+
(defn move-and-push' [[position boxes] direction]
84+
(debug' [position boxes])
85+
(let [delta (direction->delta direction)
86+
front (p+ position delta)]
87+
(loop [positions-to-check #{front}
88+
boxes-seen #{}
89+
visited #{}]
90+
(let [checking-position (first positions-to-check)
91+
box-at-position (some->> checking-position (box-at boxes))
92+
visit-unvisited
93+
(fn [positions-to-check position]
94+
(if ((conj visited checking-position) position)
95+
positions-to-check
96+
(conj positions-to-check position)))]
97+
(cond
98+
(nil? checking-position)
99+
[front
100+
(-> boxes
101+
(set/difference boxes-seen)
102+
(into (map (partial p+ delta) boxes-seen)))]
103+
104+
(contains? walls checking-position)
105+
[position boxes]
106+
107+
box-at-position
108+
(recur (-> positions-to-check
109+
(disj checking-position)
110+
(visit-unvisited box-at-position)
111+
(visit-unvisited (p+ [0 1] box-at-position))
112+
(visit-unvisited (p+ delta checking-position)))
113+
(cond-> boxes-seen box-at-position (conj box-at-position))
114+
(conj visited checking-position))
115+
116+
:else
117+
(recur (disj positions-to-check checking-position)
118+
boxes-seen
119+
(conj visited checking-position)))))))
120+
121+
(defn gps-sum' [[_ boxes]]
122+
(reduce + (map (fn [[i j]] (+ (* 100 i) j)) boxes)))
123+
124+
(gps-sum' (reduce move-and-push' [initial-position boxes] moves))

0 commit comments

Comments
 (0)