#!/usr/bin/env ruby input = (ARGV.first.nil? ? DATA : ARGF) .readlines(chomp: true) split = input.index("") gates = input[split+1..] wires = input.join(" ").scan(/([a-z0-9]{3})/).flatten.uniq.map { [_1, nil] }.to_h input[...split] .map { _1.split(": ") } .each { wires[_1] = _2.to_i } i = 0 until gates.empty? if i >= gates.size i = 0 end gate = gates[i] in1, op, in2, out = gate.scan(/([a-z0-9]{3}) ([A-Z]+) ([a-z0-9]{3}) -> ([a-z0-9]{3})/).first if wires[in1].nil? || wires[in2].nil? i += 1 next end case op when "AND" wires[out] = wires[in1] & wires[in2] when "OR" wires[out] = wires[in1] | wires[in2] when "XOR" wires[out] = wires[in1] ^ wires[in2] end gates.delete(gate) end p wires.select { _1.match?(/^z/) }.sort_by(&:first).map { _1.last.to_s }.reverse.join.to_i(2) __END__ x00: 1 x01: 0 x02: 1 x03: 1 x04: 0 y00: 1 y01: 1 y02: 1 y03: 1 y04: 1 ntg XOR fgs -> mjb y02 OR x01 -> tnw kwq OR kpj -> z05 x00 OR x03 -> fst tgd XOR rvg -> z01 vdt OR tnw -> bfw bfw AND frj -> z10 ffh OR nrd -> bqk y00 AND y03 -> djm y03 OR y00 -> psh bqk OR frj -> z08 tnw OR fst -> frj gnj AND tgd -> z11 bfw XOR mjb -> z00 x03 OR x00 -> vdt gnj AND wpb -> z02 x04 AND y00 -> kjc djm OR pbm -> qhw nrd AND vdt -> hwm kjc AND fst -> rvg y04 OR y02 -> fgs y01 AND x02 -> pbm ntg OR kjc -> kwq psh XOR fgs -> tgd qhw XOR tgd -> z09 pbm OR djm -> kpj x03 XOR y03 -> ffh x00 XOR y04 -> ntg bfw OR bqk -> z06 nrd XOR fgs -> wpb frj XOR qhw -> z04 bqk OR frj -> z07 y03 OR x01 -> nrd hwm AND bqk -> z03 tgd XOR rvg -> z12 tnw OR pbm -> gnj