81 lines
1.9 KiB
Elixir
81 lines
1.9 KiB
Elixir
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 (?<name>[A-Z]{2}) has flow rate=(?<rate>\d+); tunnels? leads? to valves? (?<tunnels>.*)/
|
|
|
|
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
|