From 1e677cbbc9d90056d5e7153549c9cee78b100770 Mon Sep 17 00:00:00 2001 From: sloane Date: Thu, 12 Dec 2024 08:47:21 -0500 Subject: [PATCH] solve 2024 day 11 --- 2024/README.md | 3 +- 2024/lib/2024/11.ex | 89 +++++++++++++++++++++++++++++++++++++++++++++ README.md | 4 +- 3 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 2024/lib/2024/11.ex diff --git a/2024/README.md b/2024/README.md index 12a9c72..a2e05b2 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 | | | | @@ -17,3 +17,4 @@ [8]: ./lib/2024/8.ex [9]: ./lib/2024/9.ex [10]: ./lib/2024/10.ex +[11]: ./lib/2024/11.ex diff --git a/2024/lib/2024/11.ex b/2024/lib/2024/11.ex new file mode 100644 index 0000000..e110743 --- /dev/null +++ b/2024/lib/2024/11.ex @@ -0,0 +1,89 @@ +import AOC +import AOC.Prelude + +aoc 2024, 11 do + require Integer + + def p1(input) do + input + |> read_stones() + |> count_stones_after_blink(25) + end + + def p2(input) do + input + |> read_stones() + |> count_stones_after_blink(75) + end + + ## + + defp count_stones_after_blink(stones, n) do + stones + |> Stream.iterate(&blink/1) + |> Enum.at(n) + |> count_stones() + end + + defp blink(stones) do + for {stone, count} <- stones, reduce: stones do + stones -> + cond do + stone == 0 -> + stones + |> remove_stones(0, count) + |> add_stones(1, count) + + even_digits?(stone) -> + {left, right} = split_stone(stone) + + stones + |> remove_stones(stone, count) + |> add_stones(left, count) + |> add_stones(right, count) + + true -> + stones + |> remove_stones(stone, count) + |> add_stones(stone * 2024, count) + end + end + end + + defp even_digits?(num) do + num + |> Integer.digits() + |> Enum.count() + |> Integer.is_even() + end + + defp split_stone(num) do + digits = Integer.digits(num) + + {left, right} = Enum.split(digits, div(length(digits), 2)) + + {Integer.undigits(left), Integer.undigits(right)} + end + + defp remove_stones(stones, num, count) do + Map.update(stones, num, 0, &(&1 - count)) + end + + defp add_stones(stones, num, count) do + Map.update(stones, num, count, &(&1 + count)) + end + + defp count_stones(stones) do + stones + |> Enum.map(&elem(&1, 1)) + |> Enum.sum() + end + + ## input + + defp read_stones(input) do + input + |> ints() + |> Enum.frequencies() + end +end diff --git a/README.md b/README.md index 1ed3b9c..c783e5c 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] | **20/50** 🌟 | Elixir | -| **Total** | **176** 🌟| | +| [2024] | **22/50** 🌟 | Elixir | +| **Total** | **178** 🌟| | [2015]: ./2015 [2017]: ./2017