Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 248ad61

Browse files
committedDec 15, 2024··
2024D15
1 parent 8ca9c66 commit 248ad61

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
 

‎notebooks/y2024/d15.clj

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
(ns y2024.d15
2+
(:require
3+
[advent-of-code-clj.utils :as utils]
4+
[advent-of-code-clj.input :as input]
5+
[clojure.core.matrix :as mx]))
6+
7+
(def test-data-small "########
8+
#..O.O.#
9+
##@.O..#
10+
#...O..#
11+
#.#.O..#
12+
#...O..#
13+
#......#
14+
########
15+
16+
<^^>>>vv<v>>v<<")
17+
18+
(def test-data-large "##########
19+
#..O..O.O#
20+
#......O.#
21+
#.OO..O.O#
22+
#..O@..O.#
23+
#O#..O...#
24+
#O..O..O.#
25+
#.OO.O.OO#
26+
#....O...#
27+
##########
28+
29+
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
30+
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
31+
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
32+
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
33+
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
34+
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
35+
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
36+
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
37+
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
38+
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^")
39+
40+
(def dir-vector {\< [0 -1]
41+
\v [1 0]
42+
\^ [-1 0]
43+
\> [0 1]})
44+
45+
(defn map-and-moves [input]
46+
(let [[game-map-str moves-str] (.split input "\n\n")
47+
game-matrix (utils/text->matrix game-map-str)
48+
coord-map (utils/coord-map-fixed game-matrix)
49+
grouped (group-by val coord-map)]
50+
{:game-state {:walls (->> (grouped \#) (map key) set)
51+
:boxes (->> (grouped \O) (map key) set)
52+
:pos (->> (grouped \@) first key)}
53+
:moves (keep dir-vector moves-str)}))
54+
55+
(map-and-moves test-data-small)
56+
57+
(defn push-boxes [walls boxes pos move]
58+
(let [path (seq (iteration (fn [x] (mapv + x move))
59+
:initk pos
60+
:somef #(not (walls %))))
61+
box-positions (map boxes path)
62+
boxes-to-move (set (take-while some? box-positions))]
63+
(if (= (count boxes-to-move) (count path))
64+
nil ; No boxes could be moved
65+
(let [remaining-boxes (remove boxes-to-move boxes)]
66+
(into (set remaining-boxes) (map (fn [box] (mapv + box move)) boxes-to-move))))))
67+
68+
(defn print-board [{:keys [pos walls boxes]}]
69+
(let [dimensions [(inc (apply max (map first walls)))
70+
(inc (apply max (map second walls)))]
71+
walls (set walls)
72+
boxes (set boxes)]
73+
(mx/pm (mx/emap-indexed (fn [idx _]
74+
(cond
75+
(walls idx) \#
76+
(boxes idx) \O
77+
(= pos idx) \@)) (apply mx/new-matrix dimensions)))))
78+
79+
(defn make-move [{:keys [pos walls boxes] :as game-state} move]
80+
(let [maybe-new-pos (mapv + pos move)]
81+
(cond
82+
(walls maybe-new-pos) game-state
83+
(boxes maybe-new-pos) (if-let [pushed-boxes (push-boxes walls boxes pos move)]
84+
(assoc game-state
85+
:pos maybe-new-pos
86+
:boxes pushed-boxes)
87+
game-state)
88+
:else (assoc game-state :pos maybe-new-pos))))
89+
90+
(defn gps-score [[y x :as _box]]
91+
(+ (* 100 y) x))
92+
93+
(defn part-1 [{:keys [game-state moves]}]
94+
(->> (reduce make-move game-state moves)
95+
(#(do
96+
(print-board %)
97+
%))
98+
:boxes
99+
(map gps-score)
100+
(reduce +)))
101+
102+
(part-1 (map-and-moves test-data-small))
103+
104+
(part-1 (map-and-moves test-data-large))
105+
106+
(delay (part-1 (map-and-moves (input/get-input 2024 15))))

0 commit comments

Comments
 (0)
Please sign in to comment.