add day20a
This commit is contained in:
parent
07674d6f0e
commit
e9a505ebd3
3 changed files with 190 additions and 0 deletions
58
23/elixir/inputs/day20.txt
Normal file
58
23/elixir/inputs/day20.txt
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
%cv -> xz
|
||||||
|
%kt -> qx, rz
|
||||||
|
%cb -> kt
|
||||||
|
%pl -> sf, db
|
||||||
|
%zd -> ln, gf
|
||||||
|
%bf -> qx, pf
|
||||||
|
%xz -> jd
|
||||||
|
%xm -> db
|
||||||
|
%vz -> cr, vc
|
||||||
|
%qq -> qm, gf
|
||||||
|
&xn -> th
|
||||||
|
%nn -> ff, db
|
||||||
|
%gx -> cd
|
||||||
|
&qn -> th
|
||||||
|
%qk -> vc
|
||||||
|
&xf -> th
|
||||||
|
%qj -> xm, db
|
||||||
|
%fn -> pr, gf
|
||||||
|
%sf -> bp
|
||||||
|
%jd -> qx, vm
|
||||||
|
%mc -> ds, db
|
||||||
|
%tj -> lc, gf
|
||||||
|
%jz -> qj, db
|
||||||
|
%sb -> ks, vc
|
||||||
|
%ln -> gf, qq
|
||||||
|
%bx -> qx, qp
|
||||||
|
broadcaster -> sr, ch, hd, bx
|
||||||
|
%ch -> db, mc
|
||||||
|
%ds -> cc
|
||||||
|
&qx -> cb, cv, bx, xz, vm, zl
|
||||||
|
%bp -> db, jz
|
||||||
|
&zl -> th
|
||||||
|
%vl -> gf, fj
|
||||||
|
&db -> ff, ds, sf, ch, cc, xf
|
||||||
|
&th -> rx
|
||||||
|
%cr -> gx, vc
|
||||||
|
%sr -> gf, vl
|
||||||
|
%lr -> sb
|
||||||
|
%hv -> lr
|
||||||
|
%cl -> qx, bf
|
||||||
|
%lc -> gf, fn
|
||||||
|
%pm -> vc, qk
|
||||||
|
%cc -> nn
|
||||||
|
%gm -> tj, gf
|
||||||
|
%vm -> cl
|
||||||
|
%ff -> pl
|
||||||
|
%qp -> cb, qx
|
||||||
|
%pf -> qx
|
||||||
|
&vc -> lr, hd, ks, qn, gx, nh, hv
|
||||||
|
%qm -> gm
|
||||||
|
%nh -> hv
|
||||||
|
%rz -> qx, cv
|
||||||
|
%ks -> vz
|
||||||
|
%fj -> zd
|
||||||
|
&gf -> fj, qm, xn, sr
|
||||||
|
%pr -> gf
|
||||||
|
%cd -> pm, vc
|
||||||
|
%hd -> vc, nh
|
5
23/elixir/inputs/day20_example.txt
Normal file
5
23/elixir/inputs/day20_example.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
broadcaster -> a, b, c
|
||||||
|
%a -> b
|
||||||
|
%b -> c
|
||||||
|
%c -> inv
|
||||||
|
&inv -> a
|
127
23/elixir/lib/days/day20.ex
Normal file
127
23/elixir/lib/days/day20.ex
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
defmodule AOC.Day20 do
|
||||||
|
# use AOC.Day, day: 20, input: "example"
|
||||||
|
use AOC.Day, day: 20
|
||||||
|
|
||||||
|
def parse_input(lines) do
|
||||||
|
modules =
|
||||||
|
lines
|
||||||
|
|> Enum.map(fn line ->
|
||||||
|
[name, destination_modules] = String.split(line, " -> ")
|
||||||
|
destination_modules = String.split(destination_modules, ", ")
|
||||||
|
|
||||||
|
case String.at(line, 0) do
|
||||||
|
"%" -> {String.trim_leading(name, "%"), {:flip_flop, destination_modules, :off}}
|
||||||
|
"&" -> {String.trim_leading(name, "&"), {:conjunction, destination_modules, %{}}}
|
||||||
|
_ -> {name, {:broadcast, destination_modules}}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|> Enum.into(%{})
|
||||||
|
|
||||||
|
Enum.reduce(modules, modules, fn {module_name, module}, acc ->
|
||||||
|
module
|
||||||
|
|> elem(1)
|
||||||
|
|> Enum.reduce(acc, fn destination_name, acc ->
|
||||||
|
case Map.fetch(acc, destination_name) do
|
||||||
|
{:ok, {:conjunction, destination_names, states} = destination_module} ->
|
||||||
|
Map.put(
|
||||||
|
acc,
|
||||||
|
destination_name,
|
||||||
|
{:conjunction, destination_names, Map.put(states, module_name, :low)}
|
||||||
|
)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def press_button(modules) do
|
||||||
|
pulse_queue = :queue.new()
|
||||||
|
pulse_queue = :queue.in({:low, "broadcaster", "button"}, pulse_queue)
|
||||||
|
|
||||||
|
propagate_pulses(modules, pulse_queue, {0, 0})
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_pulses(pulse_queue, pulse_strength, destination_names, from) do
|
||||||
|
Enum.reduce(destination_names, pulse_queue, fn destination_name, acc ->
|
||||||
|
:queue.in({pulse_strength, destination_name, from}, acc)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def propagate_pulses(modules, pulse_queue, {low_count, high_count}) do
|
||||||
|
case :queue.out(pulse_queue) do
|
||||||
|
{:empty, _} ->
|
||||||
|
{modules, {low_count, high_count}}
|
||||||
|
|
||||||
|
{{:value, {pulse_strength, module_name, from}}, pulse_queue} ->
|
||||||
|
{modules, pulse_queue} =
|
||||||
|
case Map.fetch(modules, module_name) do
|
||||||
|
:error ->
|
||||||
|
{modules, pulse_queue}
|
||||||
|
|
||||||
|
{:ok, {:broadcast, destination_names}} ->
|
||||||
|
pulse_queue =
|
||||||
|
send_pulses(pulse_queue, pulse_strength, destination_names, module_name)
|
||||||
|
|
||||||
|
{modules, pulse_queue}
|
||||||
|
|
||||||
|
{:ok, {:flip_flop, destination_names, state}} ->
|
||||||
|
case pulse_strength do
|
||||||
|
:high ->
|
||||||
|
{modules, pulse_queue}
|
||||||
|
|
||||||
|
:low ->
|
||||||
|
case state do
|
||||||
|
:off ->
|
||||||
|
module = {:flip_flop, destination_names, :on}
|
||||||
|
|
||||||
|
pulse_queue =
|
||||||
|
send_pulses(pulse_queue, :high, destination_names, module_name)
|
||||||
|
|
||||||
|
{Map.put(modules, module_name, module), pulse_queue}
|
||||||
|
|
||||||
|
:on ->
|
||||||
|
module = {:flip_flop, destination_names, :off}
|
||||||
|
pulse_queue = send_pulses(pulse_queue, :low, destination_names, module_name)
|
||||||
|
|
||||||
|
{Map.put(modules, module_name, module), pulse_queue}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, {:conjunction, destination_names, state}} ->
|
||||||
|
state = Map.put(state, from, pulse_strength)
|
||||||
|
modules = Map.put(modules, module_name, {:conjunction, destination_names, state})
|
||||||
|
all_high? = state |> Map.values() |> Enum.all?(&(&1 == :high))
|
||||||
|
|
||||||
|
pulse_queue =
|
||||||
|
if all_high? do
|
||||||
|
send_pulses(pulse_queue, :low, destination_names, module_name)
|
||||||
|
else
|
||||||
|
send_pulses(pulse_queue, :high, destination_names, module_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
{modules, pulse_queue}
|
||||||
|
end
|
||||||
|
|
||||||
|
low_count = low_count + if pulse_strength == :low, do: 1, else: 0
|
||||||
|
high_count = high_count + if pulse_strength == :high, do: 1, else: 0
|
||||||
|
|
||||||
|
propagate_pulses(modules, pulse_queue, {low_count, high_count})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def part1(modules) do
|
||||||
|
{_, {lows, highs}} =
|
||||||
|
Enum.reduce(1..1000, {modules, {0, 0}}, fn _, {modules, {low_acc, high_acc}} ->
|
||||||
|
{modules, {low, high}} = press_button(modules)
|
||||||
|
{modules, {low_acc + low, high_acc + high}}
|
||||||
|
end)
|
||||||
|
|
||||||
|
lows * highs
|
||||||
|
end
|
||||||
|
|
||||||
|
def part2(_input) do
|
||||||
|
"TODO"
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue