64 lines
1.6 KiB
Elixir
64 lines
1.6 KiB
Elixir
|
defmodule AOC.Day11.Monkey do
|
||
|
use GenServer
|
||
|
alias AOC.Day11.{MonkeyRegistry, Monkey}
|
||
|
|
||
|
@impl true
|
||
|
def init(state) do
|
||
|
{:ok, Map.put(state, :activeness, 0)}
|
||
|
end
|
||
|
|
||
|
def execute_turn(pid, ridiculous) do
|
||
|
GenServer.call(pid, {:execute_turn, ridiculous}, :infinity)
|
||
|
end
|
||
|
|
||
|
def throw(pid, item) do
|
||
|
GenServer.call(pid, {:throw, item})
|
||
|
end
|
||
|
|
||
|
def get_items(pid) do
|
||
|
GenServer.call(pid, :get_items)
|
||
|
end
|
||
|
|
||
|
def get_activeness(pid) do
|
||
|
GenServer.call(pid, :get_activeness)
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_call(
|
||
|
{:execute_turn, ridiculous},
|
||
|
_from,
|
||
|
%{
|
||
|
items: items,
|
||
|
operation: operation,
|
||
|
modulo: modulo,
|
||
|
true_monkey_id: true_monkey_id,
|
||
|
false_monkey_id: false_monkey_id,
|
||
|
activeness: activeness,
|
||
|
supermod: supermod
|
||
|
} = state
|
||
|
) do
|
||
|
Enum.each(items, fn item ->
|
||
|
item = operation.(item)
|
||
|
item = if ridiculous, do: item, else: Integer.floor_div(item, 3)
|
||
|
item = Integer.mod(item, supermod)
|
||
|
recipient = if Integer.mod(item, modulo) == 0, do: true_monkey_id, else: false_monkey_id
|
||
|
[{pid, _}] = Registry.lookup(MonkeyRegistry, recipient)
|
||
|
Monkey.throw(pid, item)
|
||
|
end)
|
||
|
|
||
|
{:reply, :ok, %{state | items: [], activeness: activeness + length(items)}}
|
||
|
end
|
||
|
|
||
|
def handle_call({:throw, item}, _from, %{items: items} = state) do
|
||
|
{:reply, :ok, Map.put(state, :items, items ++ [item])}
|
||
|
end
|
||
|
|
||
|
def handle_call(:get_items, _from, %{items: items} = state) do
|
||
|
{:reply, items, state}
|
||
|
end
|
||
|
|
||
|
def handle_call(:get_activeness, _from, %{activeness: activeness} = state) do
|
||
|
{:reply, activeness, state}
|
||
|
end
|
||
|
end
|