summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Jesus <adbjesus@gmail.com>2025-07-19 23:29:01 +0100
committerAlexandre Jesus <adbjesus@gmail.com>2025-07-19 23:29:01 +0100
commit9a8898a9d7ee0313da99232a58ca1d143b287d6a (patch)
tree5a9844ec50ae8ae49d44ca537fb18729928133af
parentcd1d84b16ac6f1de79cac0d56f05457e789e76fc (diff)
downloadaoc2024-9a8898a9d7ee0313da99232a58ca1d143b287d6a.tar.gz
aoc2024-9a8898a9d7ee0313da99232a58ca1d143b287d6a.zip
Day 22
-rw-r--r--src/day22.exs65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/day22.exs b/src/day22.exs
new file mode 100644
index 0000000..418631f
--- /dev/null
+++ b/src/day22.exs
@@ -0,0 +1,65 @@
+defmodule Day22 do
+ def part1(data, n \\ 2000) do
+ data
+ |> String.split("\n", trim: true)
+ |> Enum.map(&String.to_integer/1)
+ |> Enum.map(&(secret_numbers(&1, n)))
+ |> Enum.map(&hd/1)
+ |> Enum.sum()
+ end
+
+ defp secret_numbers(v, n) do
+ for _ <- 1..n, reduce: [v] do
+ v ->
+ [(v |> hd() |> change_value(6) |> change_value(-5) |> change_value(11)) | v]
+ end
+ end
+
+ defp change_value(v, shift) do
+ v
+ |> Bitwise.bsl(shift)
+ |> Bitwise.bxor(v)
+ |> Integer.mod(16777216)
+ end
+
+ def part2(data, n \\ 2000) do
+ data
+ |> String.split("\n", trim: true)
+ |> Enum.map(&String.to_integer/1)
+ |> Enum.map(&(secret_numbers(&1, n)))
+ |> Enum.map(&(sequences(&1, 10)))
+ |> Enum.reduce(%{}, fn s, acc ->
+ Map.merge(acc, s, fn _k, v1, v2 -> v1 + v2 end)
+ end)
+ |> Map.values()
+ |> Enum.max()
+ end
+
+ defp sequences(vs, m) do
+ vs
+ |> Enum.map(&Integer.mod(&1, m))
+ |> Enum.chunk_every(5, 1, :discard) # performance here could be improved
+ |> Enum.map(fn chunk -> {diffs(chunk), hd(chunk)} end)
+ |> Map.new()
+ end
+
+ defp diffs(vs) do
+ vs
+ |> Enum.chunk_every(2, 1, :discard)
+ |> Enum.map(fn [a, b] -> a - b end)
+ |> List.to_tuple()
+ end
+end
+
+data = IO.read(:stdio, :eof)
+
+{time1, ans1} = :timer.tc(fn -> Day22.part1(data) end)
+IO.puts("Time : #{time1 / 1000000}")
+IO.puts("Answer: #{ans1}") # 19822877190
+
+{time2, ans2} = :timer.tc(fn -> Day22.part2(data) end)
+IO.puts("Time : #{time2 / 1000000}")
+IO.puts("Answer: #{ans2}") # 2277
+
+
+