diff options
author | Alexandre Jesus <adbjesus@gmail.com> | 2025-07-19 23:29:01 +0100 |
---|---|---|
committer | Alexandre Jesus <adbjesus@gmail.com> | 2025-07-19 23:29:01 +0100 |
commit | 9a8898a9d7ee0313da99232a58ca1d143b287d6a (patch) | |
tree | 5a9844ec50ae8ae49d44ca537fb18729928133af | |
parent | cd1d84b16ac6f1de79cac0d56f05457e789e76fc (diff) | |
download | aoc2024-9a8898a9d7ee0313da99232a58ca1d143b287d6a.tar.gz aoc2024-9a8898a9d7ee0313da99232a58ca1d143b287d6a.zip |
Day 22
-rw-r--r-- | src/day22.exs | 65 |
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 + + + |