You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
1.9 KiB
Elixir
74 lines
1.9 KiB
Elixir
defmodule Day22 do
|
|
def run do
|
|
lines =
|
|
File.read!("data.txt")
|
|
|> String.trim()
|
|
|> String.split("\n")
|
|
|> Enum.map(&String.to_integer/1)
|
|
|
|
part1 =
|
|
Enum.reduce(lines, 0, fn secret, acc ->
|
|
acc + Enum.reduce(1..2000, secret, fn _, s -> evolve(s) end)
|
|
end)
|
|
|
|
dbg(part1)
|
|
|
|
# build a map of all 4-digit sequences + list index to prices
|
|
map =
|
|
Enum.with_index(lines)
|
|
|> Enum.reduce(%{}, fn {secret, idx}, map ->
|
|
{_, prices, diffs, map2} =
|
|
Enum.reduce(1..2000, {secret, [price(secret)], [], map}, fn _, {s, prices, diffs, m} ->
|
|
new_secret = evolve(s)
|
|
price = price(new_secret)
|
|
diff = price - hd(prices)
|
|
new_diff = [diff | diffs]
|
|
sec = Enum.slice(new_diff, 0, 4)
|
|
new_map = Map.put_new(m, {sec, idx}, price)
|
|
{new_secret, [price | prices], new_diff, new_map}
|
|
end)
|
|
|
|
map2
|
|
end)
|
|
|
|
# for every possible sequence (there's only like 19 ^ 4 or something)
|
|
all = for a <- -9..9, b <- -9..9, c <- -9..9, d <- -9..9, do: [a, b, c, d]
|
|
|
|
part2 =
|
|
Enum.reduce(all, {0, []}, fn sec, {max, max_sec} ->
|
|
# and for every buyer, get the price at this sequence
|
|
val =
|
|
Enum.reduce(0..length(lines), 0, fn idx, acc ->
|
|
case Map.get(map, {sec, idx}, nil) do
|
|
nil -> acc
|
|
val -> val + acc
|
|
end
|
|
end)
|
|
|
|
if val > max, do: {val, sec}, else: {max, max_sec}
|
|
end)
|
|
|
|
dbg(part2)
|
|
end
|
|
|
|
defp evolve(secret) do
|
|
step1 = secret |> Kernel.*(64) |> mix(secret) |> prune()
|
|
step2 = step1 |> div(32) |> mix(step1) |> prune()
|
|
step2 |> Kernel.*(2048) |> mix(step2) |> prune()
|
|
end
|
|
|
|
defp mix(num, secret) do
|
|
Bitwise.bxor(num, secret)
|
|
end
|
|
|
|
defp prune(num) do
|
|
Integer.mod(num, 16_777_216)
|
|
end
|
|
|
|
defp price(num) do
|
|
Integer.digits(num) |> Enum.take(-1) |> Integer.undigits()
|
|
end
|
|
end
|
|
|
|
Day22.run()
|