Skip to content

Commit 8ca9c66

Browse files
committed
Y2024D13 uten core.matrix
1 parent e433636 commit 8ca9c66

File tree

1 file changed

+84
-8
lines changed

1 file changed

+84
-8
lines changed

notebooks/y2024/d13.clj

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,20 @@ Prize: X=18641, Y=10279")
8888
; filtrerer vekk løsninger som gir ratio (feks `1/3`):
8989

9090
^{:nextjournal.clerk/visibility {:result :hide}}
91-
(defn part-1 [acc {:keys [prize a b]}]
91+
(defn tokens-needed [[a b]]
92+
(+ (* 3 a) b))
93+
94+
^{:nextjournal.clerk/visibility {:result :hide}}
95+
(defn part-1 [{:keys [prize a b]}]
9296
(let [{a 'a b 'b} (solve-game prize a b)]
9397
(if (or (< 100 a) (< 100 b)
9498
(ratio? a) (ratio? b))
95-
acc
96-
(+ acc (* a 3) b))))
99+
0
100+
(tokens-needed [a b]))))
97101

98102
^{:nextjournal.clerk/visibility {:result :hide}}
99103
(defn solve [solver input]
100-
(reduce solver 0
101-
(get-games input)))
104+
(transduce (map solver) + (get-games input)))
102105

103106
; Nå kan vi løse del 1 for test-dataene:
104107

@@ -117,14 +120,14 @@ Prize: X=18641, Y=10279")
117120
; reflektert i den nye reduceren for del 2:
118121

119122
^{:nextjournal.clerk/visibility {:result :hide}}
120-
(defn part-2 [acc {:keys [prize a b]}]
123+
(defn part-2 [{:keys [prize a b]}]
121124
(let [bigger-prize (-> prize
122125
(update :x + 10000000000000)
123126
(update :y + 10000000000000))
124127
{a 'a b 'b} (solve-game bigger-prize a b)]
125128
(if (or (ratio? a) (ratio? b))
126-
acc
127-
(+ acc (* a 3) b))))
129+
0
130+
(tokens-needed [a b]))))
128131

129132
; Ellers kan vi løse oppgaven på samme måte som i del 1 for test-input:
130133

@@ -133,3 +136,76 @@ Prize: X=18641, Y=10279")
133136
; Og faktiske input:
134137

135138
(solve part-2 (input/get-input 2024 13))
139+
140+
; ## Matriser
141+
142+
; Et alternativ til expresso er å bruke "Cramer's rule", hvor en ligning
143+
; med to ukjente og kun ett gyldig svar kan løses med matriseregning.
144+
145+
(defn transpose [matrix]
146+
(apply mapv vector matrix))
147+
148+
^{:nextjournal.clerk/visibility {:result :hide}}
149+
(defn game-matrices [input]
150+
(eduction
151+
(map (fn [game-text]
152+
(transpose (partitionv 2 (map parse-long (re-seq #"\d+" game-text))))))
153+
(.. input trim (split "\n\n"))))
154+
155+
(defn det-2d
156+
"Determinant i en 2d-matrise"
157+
[[[ax bx]
158+
[ay by]]]
159+
(- (* ax by)
160+
(* bx ay)))
161+
162+
(defn cramers-rule
163+
"I Cramer's regel er en ukjent lik determinanten av 2d-matrisen
164+
hvor en kolonne er byttet ut med løsningsvektoren, dividert med
165+
den opprinnelige 2d-matrisen."
166+
[[[ax bx rx]
167+
[ay by ry]]]
168+
(let [A [[ax bx]
169+
[ay by]]
170+
A1 [[rx bx]
171+
[ry by]]
172+
A2 [[ax rx]
173+
[ay ry]]]
174+
[(/ (det-2d A1)
175+
(det-2d A))
176+
(/ (det-2d A2)
177+
(det-2d A))]))
178+
179+
^{:nextjournal.clerk/visibility {:result :hide}}
180+
(defn solve-mx [games & {:keys [scale max-presses]
181+
:or {scale nil max-presses nil}}]
182+
(eduction
183+
(map (fn [[[ax bx rx]
184+
[ay by ry] :as matrix]]
185+
(if scale
186+
[[ax bx (+ rx scale)]
187+
[ay by (+ ry scale)]]
188+
matrix)))
189+
(map cramers-rule)
190+
(remove (fn [[a b :as _result]]
191+
(when max-presses
192+
(and (>= a max-presses)
193+
(>= b max-presses)))))
194+
(remove (fn [result] (some ratio? result)))
195+
games))
196+
197+
(->> (solve-mx (game-matrices test-data)
198+
:max-presses 100)
199+
(transduce (map tokens-needed) +))
200+
201+
(->> (solve-mx (game-matrices (input/get-input 2024 13))
202+
:max-presses 100)
203+
(transduce (map tokens-needed) +))
204+
205+
(->> (solve-mx (game-matrices test-data)
206+
:scale 10000000000000)
207+
(transduce (map tokens-needed) +))
208+
209+
(->> (solve-mx (game-matrices (input/get-input 2024 13))
210+
:scale 10000000000000)
211+
(transduce (map tokens-needed) +))

0 commit comments

Comments
 (0)