this repo has no description
1<!-- livebook:{"persist_outputs":true} -->
2
3# Day 13
4
5```elixir
6Mix.install([:kino_aoc])
7```
8
9## Section
10
11<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMyIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
12
13```elixir
14{:ok, puzzle_input} =
15 KinoAOC.download_puzzle("2024", "13", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
16```
17
18<!-- livebook:{"output":true} -->
19
20```
21{:ok,
22 "Button A: X+22, Y+88\nButton B: X+90, Y+28\nPrize: X=6496, Y=3076\n\nButton A: X+54, Y+14\nButton B: X+14, Y+44\nPrize: X=8084, Y=1284\n\nButton A: X+96, Y+15\nButton B: X+55, Y+63\nPrize: X=5535, Y=3966\n\nButton A: X+17, Y+42\nButton B: X+40, Y+25\nPrize: X=12176, Y=3136\n\nButton A: X+87, Y+31\nButton B: X+15, Y+36\nPrize: X=6672, Y=2500\n\nButton A: X+59, Y+27\nButton B: X+21, Y+56\nPrize: X=1475, Y=15098\n\nButton A: X+39, Y+51\nButton B: X+98, Y+14\nPrize: X=7890, Y=3126\n\nButton A: X+23, Y+37\nButton B: X+35, Y+14\nPrize: X=16537, Y=6184\n\nButton A: X+21, Y+89\nButton B: X+74, Y+23\nPrize: X=2407, Y=8748\n\nButton A: X+47, Y+17\nButton B: X+35, Y+59\nPrize: X=17994, Y=16242\n\nButton A: X+14, Y+45\nButton B: X+52, Y+16\nPrize: X=18768, Y=3912\n\nButton A: X+29, Y+45\nButton B: X+85, Y+11\nPrize: X=3149, Y=4161\n\nButton A: X+81, Y+95\nButton B: X+67, Y+12\nPrize: X=5489, Y=2110\n\nButton A: X+48, Y+58\nButton B: X+86, Y+22\nPrize: X=4802, Y=2280\n\nButton A: X+27, Y+59\nButton B: X+47, Y+15\nPrize: X=2602, Y=2090\n\nButton A: X+39, Y+87\nButton B: X+94, Y+38\nPrize: X=8830, Y=6134\n\nButton A: X+23, Y+61\nButton B: X+82, Y+16\nPrize: X=8405, Y=3957\n\nButton A: X+54, Y+14\nButton B: X+24, Y+63\nPrize: X=894, Y=1708\n\nButton A: X+26, Y+14\nButton B: X+18, Y+35\nPrize: X=5510, Y=12541\n\nButton A: X+65, Y+55\nButton B: X+21, Y+69\nPrize: X=430, Y=620\n\nButton A: X+11, Y+62\nButton B: X+50, Y+11\nPrize: X=11414, Y=3683\n\nButton A: X+21, Y+54\nButton B: X+93, Y+22\nPrize: X=7683, Y=5642\n\nButton A: X+20, Y+95\nButton B: X+52, Y+29\nPrize: X=5580, Y=10155\n\nButton A: X+37, Y+13\nButton B: X+11, Y+66\nPrize: X=18250, Y=14983\n\nButton A: X+54, Y+28\nButton B: X+37, Y+58\nPrize: X=17939, Y=14902\n\nButton A: X+87, Y+65\nButton B: X+11, Y+79\nPrize: X=3765, Y=4087\n\nButton A: X+74, Y+30\nButton B: X+16, Y+59\nPrize: X=9858, Y=8342\n\nButton A: X+74, Y+31\nButton B: X+17, Y+59\nPrize: X=14764, Y=6598\n\nButton A: X+12, Y+95\nButton B: X+27, Y+33\nPrize: X=945, Y=3324\n\nButton A: X+21, Y+36\nButton B: X+34, Y+14\nPrize: X=7247, Y=5012\n\nButton A: X+48, Y+62\nButton B: X+90, Y+29\nPrize: X=9150, Y=5973\n\nButton A: X+93, Y+43\nButton B: X+49, Y+91\nPrize: X=7090, Y=6422\n\nButton A: X+28, Y+70\nButton B: X+68, Y+21\nPrize: X=17176, Y=3693\n\nButton A: X+33, Y+16\nButton B: X+27, Y+51\nPrize: X=1884, Y=2771\n\nButton A: X+11, Y+43\nButton B: X+51, Y+19\nPrize: X=4114, Y=10066\n\nButton A: X+26, Y+70\nButton B: X+87, Y+46\nPrize: X=3532, Y=6874\n\nButton A: X+22, Y+35\nButton B: X+38, Y+13\nPrize: X=7508, Y=16592\n\nButton A: X+33, Y+16\nButton B: X+48, Y+72\nPrize: X=12065, Y=15896\n\nButton A: X+67, Y+25\nButton B: X+14, Y+55\nPrize: X=4093, Y=10275\n\nButton A: X+36, Y+17\nButton B: X+43, Y+77\nPrize: X=3253, Y=1933\n\nButton A: X+84, Y+24\nButton B: X+42, Y+69\nPrize: X=8862, Y=4869\n\nButton A: X+70, Y+16\nButton B: X+17, Y+68\nPrize: X=5690, Y=3224\n\nButton A: X+58, Y+27\nButton B: X+44, Y+92\nPrize: X=1890, Y=1595\n\nButton A: X+64, Y+30\nButton B: X+29, Y+57\nPrize: X=15004, Y=15224\n\nButton A: X+13, Y+90\nButton B: X+64, Y+33\nPrize: X=6560, Y=6048\n\nButton A: X+37, Y+91\nButton B: X+64, Y+49\nPrize: X=5214, Y=8379\n\nButton A: X+12, Y+80\nButton B: X+75, Y+25\nPrize: X=6684, Y=8460\n\nButton A: X+27, Y+53\nButton B: X+53, Y+30\nPrize: X=4897, Y=14148\n\nButton A: X+41, Y+11\nButton B: X+39, Y+72\nPrize: X=2818, Y=493\n\nButton A: X+74, Y+45\nButton B: X+14, Y+35\nPrize: X=8996, Y=13510\n\nButton A: X+11, Y+36\nButton B: X+86, Y+58\nPrize: X=18273, Y=14722\n\nButton A: X+99, Y+72\nButton B: X+11, Y+39\nPrize: X=2530, Y=3390\n\nButton A: X+55, Y+17\nButton B: X+22, Y+80\nPrize: X=3652, Y=6326\n\nButton A: X+11, Y+17\nButton B: X+76, Y+16\nPrize: X=5480, Y=1976\n\nButton A: X+18, Y+73\nButton B: X+28, Y+22\nPrize: X=3222, Y=4827\n\nButton A: X+14, Y+46\nButton B: X+33, Y+29\nPrize: X=2212, Y=3932\n\nButton A: X+11, Y+14\nButton B: X+80, Y+28\nPrize: X=4187, Y=2450\n\nButton A: X+28, Y+70\nButton B: X+78, Y+25\nPrize: X=2220, Y=1810\n\nButton A: X+53, Y+19\nButton B: X+73, Y+91\nPrize: X=4514, Y=2850\n\nButton A: X+21, Y+54\nButton B: X+54, Y+25\nPrize: X=5609, Y=7594\n\nButton A: X+79, Y+15\nButton B: X+16, Y+80\nPrize: X=14993, Y=17105\n\nButton A: X+20, Y+59\nButton B: X+35, Y+17\nPrize: X=10820, Y=1709\n\nButton A: X+96, Y+22\nButton B: X+24, Y+43\n" <> ...}
23```
24
25```elixir
26#puzzle_input =
27 """
28Button A: X+94, Y+34
29Button B: X+22, Y+67
30Prize: X=8400, Y=5400
31
32Button A: X+26, Y+66
33Button B: X+67, Y+21
34Prize: X=12748, Y=12176
35
36Button A: X+17, Y+86
37Button B: X+84, Y+37
38Prize: X=7870, Y=6450
39
40Button A: X+69, Y+23
41Button B: X+27, Y+71
42Prize: X=18641, Y=10279
43 """
44```
45
46<!-- livebook:{"output":true} -->
47
48```
49warning: outdented heredoc line. The contents inside the heredoc should be indented at the same level as the closing """. The following is forbidden:
50
51 def text do
52 """
53 contents
54 """
55 end
56
57Instead make sure the contents are indented as much as the heredoc closing:
58
59 def text do
60 """
61 contents
62 """
63 end
64
65The current heredoc line is indented too little
66└─ Workspace/hauleth/advent-of-code/2024/day13.livemd#cell:b6uoz4dag7jywljr:3:3
67
68```
69
70<!-- livebook:{"output":true} -->
71
72```
73"Button A: X+94, Y+34\nButton B: X+22, Y+67\nPrize: X=8400, Y=5400\n\nButton A: X+26, Y+66\nButton B: X+67, Y+21\nPrize: X=12748, Y=12176\n\nButton A: X+17, Y+86\nButton B: X+84, Y+37\nPrize: X=7870, Y=6450\n\nButton A: X+69, Y+23\nButton B: X+27, Y+71\nPrize: X=18641, Y=10279\n"
74```
75
76```elixir
77games =
78 puzzle_input
79 |> String.split("\n\n", trim: true)
80 |> Enum.map(fn game ->
81 [
82 "Button A: X+" <> <<ax::2-binary>> <> ", Y+" <> <<ay::2-binary>>,
83 "Button B: X+" <> <<bx::2-binary>> <> ", Y+" <> <<by::2-binary>>,
84 "Prize: " <> prize_pos
85 ] = String.split(game, "\n", trim: true)
86
87 ["X=" <> px, "Y=" <> py] = String.split(prize_pos, ", ")
88
89 %{
90 btn_a: {String.to_integer(ax), String.to_integer(ay)},
91 btn_b: {String.to_integer(bx), String.to_integer(by)},
92 prize: {String.to_integer(px), String.to_integer(py)}
93 }
94 end)
95```
96
97<!-- livebook:{"output":true} -->
98
99```
100[
101 %{btn_a: {22, 88}, btn_b: {90, 28}, prize: {6496, 3076}},
102 %{btn_a: {54, 14}, btn_b: {14, 44}, prize: {8084, 1284}},
103 %{btn_a: {96, 15}, btn_b: {55, 63}, prize: {5535, 3966}},
104 %{btn_a: {17, 42}, btn_b: {40, 25}, prize: {12176, 3136}},
105 %{btn_a: {87, 31}, btn_b: {15, 36}, prize: {6672, 2500}},
106 %{btn_a: {59, 27}, btn_b: {21, 56}, prize: {1475, 15098}},
107 %{btn_a: {39, 51}, btn_b: {98, 14}, prize: {7890, 3126}},
108 %{btn_a: {23, 37}, btn_b: {35, 14}, prize: {16537, 6184}},
109 %{btn_a: {21, 89}, btn_b: {74, 23}, prize: {2407, 8748}},
110 %{btn_a: {47, 17}, btn_b: {35, 59}, prize: {17994, 16242}},
111 %{btn_a: {14, 45}, btn_b: {52, 16}, prize: {18768, 3912}},
112 %{btn_a: {29, 45}, btn_b: {85, 11}, prize: {3149, 4161}},
113 %{btn_a: {81, 95}, btn_b: {67, 12}, prize: {5489, 2110}},
114 %{btn_a: {48, 58}, btn_b: {86, 22}, prize: {4802, 2280}},
115 %{btn_a: {27, 59}, btn_b: {47, 15}, prize: {2602, 2090}},
116 %{btn_a: {39, 87}, btn_b: {94, 38}, prize: {8830, 6134}},
117 %{btn_a: {23, 61}, btn_b: {82, 16}, prize: {8405, 3957}},
118 %{btn_a: {54, 14}, btn_b: {24, 63}, prize: {894, 1708}},
119 %{btn_a: {26, 14}, btn_b: {18, 35}, prize: {5510, 12541}},
120 %{btn_a: {65, 55}, btn_b: {21, 69}, prize: {430, 620}},
121 %{btn_a: {11, 62}, btn_b: {50, 11}, prize: {11414, 3683}},
122 %{btn_a: {21, 54}, btn_b: {93, 22}, prize: {7683, 5642}},
123 %{btn_a: {20, 95}, btn_b: {52, 29}, prize: {5580, 10155}},
124 %{btn_a: {37, 13}, btn_b: {11, 66}, prize: {18250, 14983}},
125 %{btn_a: {54, 28}, btn_b: {37, 58}, prize: {17939, 14902}},
126 %{btn_a: {87, 65}, btn_b: {11, 79}, prize: {3765, 4087}},
127 %{btn_a: {74, 30}, btn_b: {16, 59}, prize: {9858, 8342}},
128 %{btn_a: {74, 31}, btn_b: {17, 59}, prize: {14764, 6598}},
129 %{btn_a: {12, 95}, btn_b: {27, 33}, prize: {945, 3324}},
130 %{btn_a: {21, 36}, btn_b: {34, 14}, prize: {7247, 5012}},
131 %{btn_a: {48, 62}, btn_b: {90, 29}, prize: {9150, 5973}},
132 %{btn_a: {93, 43}, btn_b: {49, 91}, prize: {7090, 6422}},
133 %{btn_a: {28, 70}, btn_b: {68, 21}, prize: {17176, 3693}},
134 %{btn_a: {33, 16}, btn_b: {27, 51}, prize: {1884, 2771}},
135 %{btn_a: {11, 43}, btn_b: {51, 19}, prize: {4114, 10066}},
136 %{btn_a: {26, 70}, btn_b: {87, 46}, prize: {3532, 6874}},
137 %{btn_a: {22, 35}, btn_b: {38, 13}, prize: {7508, 16592}},
138 %{btn_a: {33, 16}, btn_b: {48, 72}, prize: {12065, 15896}},
139 %{btn_a: {67, 25}, btn_b: {14, 55}, prize: {4093, 10275}},
140 %{btn_a: {36, 17}, btn_b: {43, 77}, prize: {3253, 1933}},
141 %{btn_a: {84, 24}, btn_b: {42, 69}, prize: {8862, 4869}},
142 %{btn_a: {70, 16}, btn_b: {17, 68}, prize: {5690, 3224}},
143 %{btn_a: {58, 27}, btn_b: {44, 92}, prize: {1890, 1595}},
144 %{btn_a: {64, 30}, btn_b: {29, 57}, prize: {15004, 15224}},
145 %{btn_a: {13, 90}, btn_b: {64, 33}, prize: {6560, 6048}},
146 %{btn_a: {37, 91}, btn_b: {64, 49}, prize: {5214, ...}},
147 %{btn_a: {12, 80}, btn_b: {75, ...}, prize: {...}},
148 %{btn_a: {27, ...}, btn_b: {...}, ...},
149 %{btn_a: {...}, ...},
150 %{...},
151 ...
152]
153```
154
155Yay, matrices again. We need to solve linear equations in form of:
156
157$$
158\begin{cases}
159a_x x & + & b_x y & = & p_x \\
160a_y x & + & b_x y & = & p_y
161\end{cases}
162$$
163
164So we need to solve:
165
166$$
167\begin{bmatrix}
168a_x & b_x \\
169a_y & b_y
170\end{bmatrix}
171\begin{bmatrix}
172x \\
173y
174\end{bmatrix}
175= \begin{bmatrix}
176p_x \\
177p_y
178\end{bmatrix}
179$$
180
181For each game. So we can use [Cramer's Rule](https://en.wikipedia.org/wiki/Cramer%27s_rule).
182
183$$
184\begin{gather*}
185x = \frac{\text{det}(A_x)}{\text{det}(A)} \\
186y = \frac{\text{det}(A_y)}{\text{det}(A)}
187\end{gather*}
188$$
189
190Assuming that $\text{det}(A) \ne 0$ (otherwise there will be no solution). In case of $2\times2$ matrices determinant is simple to compute:
191
192$$
193\text{det}
194\begin{vmatrix}
195a & b \\
196c & d
197\end{vmatrix}
198= ad - bc
199$$
200
201So in the end we need to compute:
202
203$$
204\begin{gather*}
205x = \frac{p_x b_y - b_x p_y}{a_x b_y - b_x a_y} \\
206y = \frac{a_x p_y - p_x a_y}{a_x b_y - b_x a_y}
207\end{gather*}
208$$
209
210And reject cases where $x$ or $y$ is non-integer value.
211
212```elixir
213defmodule Game do
214 def solve(%{btn_a: {ax, ay}, btn_b: {bx, by}, prize: {px, py}}) do
215 det_a = ax * by - bx * ay
216 det_x = px * by - bx * py
217 det_y = ax * py - px * ay
218
219 if rem(det_x, det_a) == 0 do
220 {div(det_x, det_a), div(det_y, det_a)}
221 end
222 end
223end
224```
225
226<!-- livebook:{"output":true} -->
227
228```
229{:module, Game, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:solve, 1}}
230```
231
232## Part 1
233
234```elixir
235games
236|> Enum.map(&Game.solve/1)
237|> Enum.map(fn
238 nil -> 0
239 {a, b} -> a * 3 + b * 1
240end)
241|> Enum.sum()
242```
243
244<!-- livebook:{"output":true} -->
245
246```
24731897
248```
249
250## Part 2
251
252```elixir
253games
254|> Enum.map(fn %{prize: {px, py}} = game ->
255 add = 10_000_000_000_000
256 %{game | prize: {px + add, py + add}}
257end)
258|> Enum.map(&Game.solve/1)
259|> Enum.map(fn
260 nil -> 0
261 {a, b} -> a * 3 + b * 1
262end)
263|> Enum.sum()
264```
265
266<!-- livebook:{"output":true} -->
267
268```
26987596249540359
270```
271
272<!-- livebook:{"offset":11449,"stamp":{"token":"XCP.AhVykQ8wyKxhTI29dXZZ0BnWEqWCuVGz8E2TRFpScgbUfqJJtY47yrvU9g9OzcejZVc8LbU3ak4YrgSGy5A5XeARPC3qt5fGPV4K9PYS3YabI7-q8rCKi8R6ZpGBpmZeDNQ","version":2}} -->