Skip to content

Commit 3d632d7

Browse files
committed
Day 16: Solve part 1 and 2
1 parent a496300 commit 3d632d7

File tree

2 files changed

+106
-13
lines changed

2 files changed

+106
-13
lines changed

Diff for: src/advent_of_code_2023/day16.clj

+92-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,97 @@
11
(ns advent-of-code-2023.day16
22
(:require
3-
[advent-of-code-2023.utils.string :as u]))
3+
[advent-of-code-2023.utils.graph :as g]))
44

5-
(defn parse-input [input])
5+
;; For debug purposes
6+
(defn- assoc-beams [{:keys [positions] :as c} [x y dir]]
7+
(if (#{\| \- \\ \/} (positions [x y]))
8+
c
9+
(assoc-in c [:positions [x y]]
10+
(condp = dir
11+
:north \^
12+
:east \>
13+
:south \v
14+
:west \<
15+
:?))))
616

7-
(defn day16-1 [parsed-input])
17+
;; For debug purposes
18+
(defn- assoc-energized [c [x y]]
19+
(assoc-in c [:positions [x y]] \#))
820

9-
(defn day16-2 [parsed-input])
21+
(defn parse-input [input]
22+
(g/parse-positional-map input identity))
23+
24+
(defn- move-beam [[_ _ direction :as position]]
25+
(condp = direction
26+
:north (update position 1 dec)
27+
:east (update position 0 inc)
28+
:south (update position 1 inc)
29+
:west (update position 0 dec)))
30+
31+
(defn- split-beam [dir val [x y]]
32+
(condp = [dir val]
33+
[:east \|] [[x y :north] [x y :south]]
34+
[:west \|] [[x y :north] [x y :south]]
35+
[:north \-] [[x y :east] [x y :west]]
36+
[:south \-] [[x y :east] [x y :west]]
37+
nil))
38+
39+
(defn- trace-beam
40+
([contraption start-pos]
41+
(trace-beam contraption start-pos #{}))
42+
([{:keys [positions] :as contraption} beam-position beam-positions]
43+
(let [[x y dir :as np] (move-beam beam-position)
44+
val (positions (butlast np))]
45+
;; It is not enough to currently be in the same position and same direction
46+
;; for a cycle. We also need to have come from the same position
47+
(if (and (beam-positions beam-position) (beam-positions np))
48+
beam-positions
49+
(condp = val
50+
;; We are outside of the grid -> stop
51+
nil (conj beam-positions beam-position)
52+
\. (recur contraption np (conj beam-positions beam-position))
53+
\| (if-let [[dir1 dir2] (split-beam dir val np)]
54+
(let [up-beam-positions
55+
(trace-beam contraption dir1 (conj beam-positions beam-position))]
56+
(recur contraption dir2 up-beam-positions))
57+
;; We simply pass through the mirror
58+
(recur contraption np (conj beam-positions beam-position)))
59+
\- (if-let [[dir1 dir2] (split-beam dir val np)]
60+
(let [left-beam-positions
61+
(trace-beam contraption dir1 (conj beam-positions beam-position))]
62+
(trace-beam contraption dir2 left-beam-positions))
63+
;; We simply pass through the mirror
64+
(recur contraption np (conj beam-positions beam-position)))
65+
\\ (recur contraption [x y (condp = dir
66+
:north :west
67+
:south :east
68+
:east :south
69+
:west :north)]
70+
(conj beam-positions beam-position))
71+
\/ (recur contraption [x y (condp = dir
72+
:north :east
73+
:south :west
74+
:east :north
75+
:west :south)]
76+
(conj beam-positions beam-position)))))))
77+
78+
(defn- energy [beam-positions]
79+
;; We have to subtract one, because our result also contains the
80+
;; start point otuside of the grid
81+
(dec (count (set (mapv butlast beam-positions)))))
82+
83+
(defn- day16 [contraption beam-start]
84+
(energy (trace-beam contraption beam-start)))
85+
86+
(defn day16-1 [contraption]
87+
(day16 contraption [-1 0 :east]))
88+
89+
(defn day16-2 [{:keys [height width] :as contraption}]
90+
(let [beam-starts (concat
91+
(for [x (range width)] [x -1 :south])
92+
(for [x (range width)] [x height :north])
93+
(for [y (range height)] [-1 y :east])
94+
(for [y (range height)] [width y :west]))]
95+
(->> beam-starts
96+
(pmap (partial day16 contraption))
97+
(reduce max))))

Diff for: test/advent_of_code_2023/day16_test.clj

+14-9
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,31 @@
44
[advent-of-code-2023.day16 :refer :all]
55
[advent-of-code-2023.test-utils :as tu]))
66

7-
(defonce ^:private example-input (parse-input ""))
7+
(defonce ^:private example-input (parse-input ".|...\\....
8+
|.-.\\.....
9+
.....|-...
10+
........|.
11+
..........
12+
.........\\
13+
..../.\\\\..
14+
.-.-/..|..
15+
.|....-|.\\
16+
..//.|...."))
817

918
(def ^:private input (parse-input (tu/slurp-input "resources/day16.txt")))
1019

1120
(deftest day16-1-example-test
1221
(testing "day16-1 example"
13-
(is (= nil
14-
(day16-1 example-input)))))
22+
(is (= 46 (day16-1 example-input)))))
1523

1624
(deftest day16-1-test
1725
(testing "day16-1"
18-
(is (= nil
19-
(day16-1 input)))))
26+
(is (= 6855 (day16-1 input)))))
2027

2128
(deftest day16-2-example-test
2229
(testing "day16-2 example"
23-
(is (= nil
24-
(day16-2 example-input)))))
30+
(is (= 51 (day16-2 example-input)))))
2531

2632
(deftest day16-2-test
2733
(testing "day16-2"
28-
(is (= nil
29-
(day16-2 input)))))
34+
(is (= 7513 (day16-2 input)))))

0 commit comments

Comments
 (0)