defmodule Day24 do def run do {wires, gates} = parse_input("data.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: left, right: right, output: output, op: op}, acc -> l = Map.get(wires, left, nil) r = Map.get(wires, right, nil) if !is_nil(l) and !is_nil(r) do Map.put(acc, output, op.(l, r)) 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 [%{left: left, right: right, op: op, output: output} | map] end) {wires, gates} end end Day24.run()