1
0
Fork 0
advent-of-code-2024/24/main.rb
2024-12-24 20:45:09 -05:00

79 lines
1.5 KiB
Ruby

#!/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
x = wires.select { _1.match?(/^x/) }.sort_by(&:first).map { _1.last.to_s }.reverse.join
xi = x.to_i(2)
y = wires.select { _1.match?(/^y/) }.sort_by(&:first).map { _1.last.to_s }.reverse.join
yi = y.to_i(2)
z = wires.select { _1.match?(/^z/) }.sort_by(&:first).map { _1.last.to_s }.reverse.join
zi = z.to_i(2)
gates = input[split+1..]
(x.size - 1).downto(0).each do |i|
if x[i].to_i ^ y[i].to_i != z[i + 1].to_i
p " " + x
p " " + y
p z
p (" " * (i + 1)) + "^"
# require"debug";debugger
puts "Failed XOR at #{i}: #{gates.select { _1.match?(/z#{'%02d' % i}/) }}"
break
end
end
__END__
x00: 0
x01: 1
x02: 0
x03: 1
x04: 0
x05: 1
y00: 0
y01: 0
y02: 1
y03: 1
y04: 0
y05: 1
x00 AND y00 -> z05
x01 AND y01 -> z02
x02 AND y02 -> z01
x03 AND y03 -> z03
x04 AND y04 -> z04
x05 AND y05 -> z00