117 lines
2.3 KiB
Markdown
117 lines
2.3 KiB
Markdown
# AOC 2024 Day 22
|
|
|
|
```elixir
|
|
[{:kino_benchee, "~> 0.1.0"}] |> Mix.install
|
|
```
|
|
|
|
## Section
|
|
|
|
```elixir
|
|
input = """
|
|
""" |> String.split("\n", trim: true)
|
|
|> Enum.map(&String.to_integer/1)
|
|
```
|
|
|
|
## Section
|
|
|
|
```elixir
|
|
defmodule MonkeyMarket do
|
|
@doc """
|
|
|
|
## Example
|
|
iex> MonkeyMarket.enc_base19([-1,0,9,-9])
|
|
-9+10+20*(19+20*(10+20*(9)))
|
|
"""
|
|
def enc_base19(ints) do
|
|
ints
|
|
|> Enum.reduce(
|
|
0,
|
|
fn i, acc -> acc * 20 + i + 10 end
|
|
)
|
|
end
|
|
|
|
|
|
@doc """
|
|
## Example
|
|
iex> MonkeyMarket.dec_base19(-9+10+20*(19+20*(10+20*(9))))
|
|
[-1,0,9,-9]
|
|
"""
|
|
def dec_base19(i) do
|
|
dec_base19(i, [])
|
|
end
|
|
defp dec_base19(0, acc), do: acc
|
|
defp dec_base19(i, acc) do
|
|
dec_base19(div(i,20),[Integer.mod(i, 20)-10 | acc])
|
|
end
|
|
|
|
@doc """
|
|
|
|
## Example
|
|
iex> MonkeyMarket.part2([1,2,3,2024])
|
|
23
|
|
"""
|
|
def part2(input) do
|
|
tasks = for j <- input do
|
|
Task.async(fn ->
|
|
diffs = MonkeyMarket.next(j, 2000)
|
|
|> Stream.map(&rem(&1, 10))
|
|
|> Enum.reverse()
|
|
|> Stream.chunk_every(2, 1, :discard)
|
|
|> Stream.map(fn [a,b] -> {b, b-a} end)
|
|
|
|
for [_,_,_,{n,_}] = chunk <- diffs
|
|
|> Stream.chunk_every(4, 1, :discard),
|
|
chunk = chunk |> Enum.map(&(elem(&1, 1))),
|
|
reduce: %{} do
|
|
acc2 ->
|
|
acc2 |> Map.put_new(chunk |> enc_base19, n)
|
|
end
|
|
end)
|
|
end
|
|
|
|
for m <- Task.await_many(tasks, :infinity), reduce: %{} do
|
|
acc -> Map.merge(
|
|
m,
|
|
acc,
|
|
fn _, s1, s2 ->
|
|
s1+s2
|
|
end
|
|
)
|
|
end
|
|
|> Enum.max_by(&elem(&1, 1))
|
|
|> elem(1)
|
|
end
|
|
@doc """
|
|
|
|
## Example
|
|
iex> MonkeyMarket.part1([1,10,100,2024])
|
|
37327623
|
|
"""
|
|
def part1(input) do
|
|
input
|
|
|> Stream.map(&hd(MonkeyMarket.next(&1, 2000)))
|
|
|> Enum.sum()
|
|
end
|
|
|
|
def next(a) do
|
|
a = a |> Bitwise.bsl(6) |> Bitwise.bxor(a) |> Bitwise.band(16777215)
|
|
a = a |> Bitwise.bsr(5) |> Bitwise.bxor(a) |> Bitwise.band(16777215)
|
|
a |> Bitwise.bsl(11) |> Bitwise.bxor(a) |> Bitwise.band(16777215)
|
|
end
|
|
|
|
def next(a, x) when is_integer(a), do: next([a], x)
|
|
def next(a, 0), do: a
|
|
def next([prev | _ ] = a, n), do: next([next(prev) | a], n - 1)
|
|
end
|
|
```
|
|
|
|
```elixir
|
|
MonkeyMarket.part2(input)
|
|
```
|
|
|
|
```elixir
|
|
Benchee.run(%{
|
|
part1: fn -> MonkeyMarket.part1(input) end
|
|
})
|
|
|
|
```
|