diff --git a/2024/README.md b/2024/README.md index dedd619..bbcefa6 100644 --- a/2024/README.md +++ b/2024/README.md @@ -3,7 +3,7 @@ | S | M | T | W | T | F | S | | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | [1] | [2] | [3] | [4] | [5] | [6] | [7] | -| [8] | [9] | [10]| [11]| [12]| 13 | 14 | +| [8] | [9] | [10]| [11]| [12]| [13]| 14 | | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | 22 | 23 | 24 | 25 | | | | @@ -19,3 +19,4 @@ [10]: ./lib/2024/10.ex [11]: ./lib/2024/11.ex [12]: ./lib/2024/12.ex +[13]: ./lib/2024/13.ex diff --git a/2024/lib/2024/13.ex b/2024/lib/2024/13.ex new file mode 100644 index 0000000..d8d9c66 --- /dev/null +++ b/2024/lib/2024/13.ex @@ -0,0 +1,76 @@ +import AOC + +aoc 2024, 13 do + def p1(input) do + input + |> read_machines() + |> Enum.map(&solve/1) + |> Enum.filter(&match?({:solution, a, b} when a <= 100 and b <= 100, &1)) + |> Enum.map(&tokens_for_solution/1) + |> Enum.sum() + end + + def p2(input) do + input + |> read_machines() + |> Enum.map(fn %{goal: {x, y}} = machine -> + %{machine | goal: {x + 10_000_000_000_000, y + 10_000_000_000_000}} + end) + |> Enum.map(&solve/1) + |> Enum.map(&tokens_for_solution/1) + |> Enum.sum() + end + + defp solve(%{a: {ax, ay}, b: {bx, by}, goal: {x, y}}) do + # a * ax + b * bx = x + # a * ay + b * by = y + + # a * ax + b * bx = x + # a * ax = x - b * bx + # a = (x - b * bx) / ax + + # a * ay + b * by = y + # ((x - b * bx) / ax) * ay + b * by = y + # ((ay * (x - b * bx)) / ax) + b * by = y + # ((ay * x - ay * b * bx) / ax) + b * by = y + # ay * x - ay * b * bx + b * by * ax = y * ax + # b * by * ax - b * ay * bx = y * ax - x * ay + # b * (by * ax - ay * bx) = y * ax - x * ay + # b = (y * ax - x * ay) / (by * ax - ay * bx) + + b = div(y * ax - x * ay, by * ax - ay * bx) + a = div(x - b * bx, ax) + + if a * ax + b * bx == x and a * ay + b * by == y do + {:solution, a, b} + else + :impossible + end + end + + defp tokens_for_solution({:solution, a, b}) do + 3 * a + b + end + + defp tokens_for_solution(_), do: 0 + + ## input + + defp read_machines(str) do + ~r/Button A: X\+(\d+), Y\+(\d+)\nButton B: X\+(\d+), Y\+(\d+)\nPrize: X=(\d+), Y=(\d+)/m + |> Regex.scan( + str, + capture: :all_but_first + ) + |> Enum.map(fn strings -> + [xa, ya, xb, yb, x, y] = + Enum.map(strings, &String.to_integer/1) + + %{ + a: {xa, ya}, + b: {xb, yb}, + goal: {x, y} + } + end) + end +end diff --git a/README.md b/README.md index 7bf0285..2670488 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ | [2021] | **43/50** 🌟 | Elixir | | [2022] | **14/50** 🌟 | Elixir, Haskell | | [2023] | **19/50** 🌟 | Elixir, Haskell | -| [2024] | **24/50** 🌟 | Elixir | -| **Total** | **180** 🌟| | +| [2024] | **26/50** 🌟 | Elixir | +| **Total** | **182** 🌟| | [2015]: ./2015 [2017]: ./2017