Day 24. Got part 1 pretty easily, but now I\'m not sure I should be using maps for the gates. Checking in now so I can refactor into just lists
parent
2cd1da3932
commit
791d6d9c69
@ -0,0 +1,91 @@
|
|||||||
|
defmodule Day24 do
|
||||||
|
def run do
|
||||||
|
{wires, gates} = parse_input("test.txt")
|
||||||
|
|
||||||
|
# part1
|
||||||
|
part1 = run_loop(wires, gates) |> wire_value("z") |> b_to_d()
|
||||||
|
dbg(part1)
|
||||||
|
|
||||||
|
# part2
|
||||||
|
x = wire_value(wires, "x") |> b_to_d()
|
||||||
|
y = wire_value(wires, "y") |> b_to_d()
|
||||||
|
target = (x + y) |> d_to_b()
|
||||||
|
dbg(target)
|
||||||
|
dbg(b_to_d(target))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp b_to_d(bin) do
|
||||||
|
:erlang.binary_to_integer(Integer.to_string(bin), 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp d_to_b(dec) do
|
||||||
|
Integer.to_string(dec, 2) |> String.to_integer()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp wire_value(wires, char) do
|
||||||
|
wires
|
||||||
|
|> Enum.filter(fn {k, _} -> String.starts_with?(k, char) end)
|
||||||
|
|> Enum.sort()
|
||||||
|
|> Enum.reduce([], fn {_, v}, acc -> [v | acc] end)
|
||||||
|
|> Integer.undigits()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp run_loop(wires, gates) do
|
||||||
|
new_wires = run(wires, gates)
|
||||||
|
|
||||||
|
if map_size(new_wires) == map_size(wires) do
|
||||||
|
wires
|
||||||
|
else
|
||||||
|
run_loop(new_wires, gates)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp run(wires, gates) do
|
||||||
|
Enum.reduce(gates, wires, fn {{left, right}, effects}, acc ->
|
||||||
|
l = Map.get(wires, left, nil)
|
||||||
|
r = Map.get(wires, right, nil)
|
||||||
|
|
||||||
|
if !is_nil(l) and !is_nil(r) do
|
||||||
|
Enum.reduce(effects, acc, fn {op, output}, acc2 ->
|
||||||
|
res = op.(l, r)
|
||||||
|
Map.put(acc2, output, res)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parse_input(file) do
|
||||||
|
[wires, gates] =
|
||||||
|
File.read!(file)
|
||||||
|
|> String.trim()
|
||||||
|
|> String.split("\n\n")
|
||||||
|
|> Enum.map(&String.split(&1, "\n"))
|
||||||
|
|
||||||
|
wires =
|
||||||
|
Enum.reduce(wires, %{}, fn el, map ->
|
||||||
|
[wire, value] = String.split(el, ": ")
|
||||||
|
Map.put(map, wire, String.to_integer(value))
|
||||||
|
end)
|
||||||
|
|
||||||
|
gates =
|
||||||
|
Enum.reduce(gates, %{}, fn el, map ->
|
||||||
|
[logic, output] = String.split(el, " -> ")
|
||||||
|
[left, op, right] = String.split(logic, " ")
|
||||||
|
|
||||||
|
op =
|
||||||
|
case op do
|
||||||
|
"AND" -> &Bitwise.band/2
|
||||||
|
"OR" -> &Bitwise.bor/2
|
||||||
|
"XOR" -> &Bitwise.bxor/2
|
||||||
|
end
|
||||||
|
|
||||||
|
Map.update(map, {left, right}, [{op, output}], fn acc -> [{op, output} | acc] end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
{wires, gates}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Day24.run()
|
Loading…
Reference in New Issue