summaryrefslogtreecommitdiffstats
path: root/src/day22.exs
diff options
context:
space:
mode:
Diffstat (limited to 'src/day22.exs')
-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
+
+
+