aoc/22/lib/days/day11/monkey.ex

64 lines
1.6 KiB
Elixir
Raw Normal View History

2023-04-17 18:18:20 +00:00
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