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