From 791d6d9c699ed0947bed9c9390e5953cd5c59834 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sun, 29 Dec 2024 17:50:28 -0700 Subject: [PATCH] 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 --- day24/main.exs | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 day24/main.exs diff --git a/day24/main.exs b/day24/main.exs new file mode 100644 index 0000000..7aa3bbc --- /dev/null +++ b/day24/main.exs @@ -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()