defmodule AOC.Day16 do use AOC.Day, day: 16, debug: true, input: "example" alias AOC.Day16.{ValveRegistry, Valve} defmodule Valve do use GenServer @impl true def init(state) do state = Map.put(state, :released, 0) state = Map.put(state, :open?, false) {:ok, state} end def get_rate(valve) do GenServer.call(valve, :get_rate) end def tick(valve) do GenServer.call(valve, :tick) end def open(valve) do GenServer.call(valve, :open) end @impl true def handle_call(:get_rate, _from, %{rate: rate} = state) do {:reply, rate, state} end def handle_call(:tick, _from, %{open?: open?, released: released, rate: rate} = state) do released = if open?, do: released + rate, else: released {:reply, :ok, %{state | released: released}} end def handle_call(:open, _from, state) do {:reply, :ok, %{state | open?: true}} end end @line_regex ~r/Valve (?[A-Z]{2}) has flow rate=(?\d+); tunnels? leads? to valves? (?.*)/ def parse_input(lines) do {:ok, _} = Registry.start_link(keys: :unique, name: ValveRegistry) lines |> Enum.map(fn line -> %{"name" => name, "rate" => rate, "tunnels" => tunnels} = Regex.named_captures(@line_regex, line) %{name: name, rate: String.to_integer(rate), tunnels: String.split(tunnels, ", ")} end) |> Enum.into(%{}, fn %{name: name} = valve -> {:ok, pid} = GenServer.start_link(Valve, valve, name: {:via, Registry, {ValveRegistry, name}}) {name, pid} end) end def part1(valves) do Enum.map(valves, fn {name, valve} -> rate = Valve.get_rate(valve) {name, rate} end) |> Enum.sort_by(&elem(&1, 1), :desc) |> IO.inspect() :ok end def tick(valves) do Enum.each(valves, fn {_, valve} -> Valve.tick(valve) end) end def part2(_input) do end end