do day 15 part 2
This commit is contained in:
+64
-39
@@ -6,7 +6,7 @@
|
||||
|
||||
;; parse input
|
||||
(let [[a b] (c/split-on-double-newlines
|
||||
(get-input-raw 15))
|
||||
(get-input-raw 2024 15))
|
||||
raw-grid (->> (str/split-lines a)
|
||||
c/map-by-coords)]
|
||||
(def instructions (->> (filter #(not= % \newline) b)
|
||||
@@ -14,52 +14,77 @@
|
||||
(def start (->> (filter #(= (second %) \@) raw-grid)
|
||||
ffirst))
|
||||
(def grid (assoc raw-grid start \.))
|
||||
|
||||
(def grid-2 (->> (str/replace a "O" ".")
|
||||
str/split-lines
|
||||
(mapv #(apply str (interleave % %)))
|
||||
c/map-by-coords))
|
||||
|
||||
(def boulders-2 (->> (filter #(= (second %) \O) raw-grid)
|
||||
(map first)
|
||||
(map #(update % 0 * 2))
|
||||
set))
|
||||
|
||||
(def walls-2 (->> (filter #(= (second %) \#) grid-2)
|
||||
(map first)
|
||||
set)))
|
||||
(def grid-2 (into {} (mapcat (fn [[[row col] chr]]
|
||||
[[[row (* 2 col)] (condp = chr \O \[ chr)]
|
||||
[[row (inc (* 2 col))] (condp = chr \O \] chr)]])
|
||||
grid)))
|
||||
(def start-2 (update start 1 * 2)))
|
||||
|
||||
(def step-fns {:up [0 dec]
|
||||
:down [0 inc]
|
||||
:right [1 inc]
|
||||
:left [1 dec]})
|
||||
|
||||
(defn step [loc dir]
|
||||
(apply update loc (step-fns dir)))
|
||||
|
||||
(defn blocks-to-move
|
||||
([grid loc dir] (blocks-to-move grid loc dir #{}))
|
||||
([grid loc dir boulders]
|
||||
(let [check (step loc dir)
|
||||
checked-val (grid check)]
|
||||
(cond
|
||||
(not boulders) boulders
|
||||
|
||||
(= checked-val \O)
|
||||
(recur grid check dir (conj boulders check))
|
||||
|
||||
(#{\[ \]} checked-val)
|
||||
(let [alt-check (step check (if (= checked-val \[)
|
||||
:right
|
||||
:left))]
|
||||
(as-> boulders v
|
||||
(if (or (not v) (contains? boulders check))
|
||||
v
|
||||
(blocks-to-move grid check dir
|
||||
(conj v check)))
|
||||
(if (or (not v) (contains? v alt-check))
|
||||
v
|
||||
(blocks-to-move grid alt-check dir (conj v alt-check)))))
|
||||
|
||||
(= checked-val \.) boulders
|
||||
|
||||
:else nil))))
|
||||
|
||||
(defn update-grid-helper [{:keys [grid loc]} dir]
|
||||
(let [check (step loc dir)
|
||||
to-move (or (blocks-to-move grid loc dir) #{})
|
||||
grid' (as-> grid v
|
||||
(reduce #(assoc %1 %2 \.) v to-move)
|
||||
(reduce #(assoc %1 (step %2 dir) (grid %2)) v to-move))
|
||||
checked-val (grid' check)
|
||||
loc' (if (= checked-val \.)
|
||||
check
|
||||
loc)]
|
||||
{:grid grid'
|
||||
:loc loc'}))
|
||||
|
||||
;; part 1
|
||||
(->> instructions
|
||||
(reduce (fn [{:keys [grid loc] :as acc}
|
||||
dir]
|
||||
(let [check (step loc dir)
|
||||
gap (loop [p check]
|
||||
(condp = (grid p)
|
||||
nil nil
|
||||
\# nil
|
||||
\O (recur (step p dir))
|
||||
\. p))] ; hey look, some space!
|
||||
(cond
|
||||
(nil? gap) acc
|
||||
(reduce update-grid-helper {:grid grid, :loc start})
|
||||
:grid
|
||||
(filter #(= (second %) \O))
|
||||
(map first)
|
||||
(map #(+ (second %)
|
||||
(* 100 (first %))))
|
||||
(reduce +))
|
||||
|
||||
(= gap check) (assoc acc :loc check)
|
||||
|
||||
:else {:loc check
|
||||
:grid (-> grid
|
||||
(assoc check \.)
|
||||
(assoc gap \O))})))
|
||||
{:grid grid, :loc start})
|
||||
:grid
|
||||
(filter #(= (second %) \O))
|
||||
(map first)
|
||||
(map #(+ (second %)
|
||||
(* 100 (first %))))
|
||||
(reduce +))
|
||||
;; part 2
|
||||
(->> instructions
|
||||
(reduce update-grid-helper {:grid grid-2, :loc start-2})
|
||||
:grid
|
||||
(filter #(#{\[} (second %)))
|
||||
(map first)
|
||||
(map #(+ (second %)
|
||||
(* 100 (first %))))
|
||||
(reduce +))
|
||||
|
||||
Reference in New Issue
Block a user