2015/07/script.rb

77 lines
2.0 KiB
Ruby
Executable File

#!/usr/bin/env ruby
require_relative '../common'
class Integer
def bitwise_complement
self ^ 65535
end
end
class Day07 < Day
def part1
wires = input.each_with_object({}) do |row, hash|
instruction, wire = row.split(' -> ')
hash[wire] = Instruction.new(instruction)
end
wires.map { |wire, instruction| [wire, instruction.signal(wires)] }.sort.to_h.fetch('a')
end
def part2
wires = input.each_with_object({}) do |row, hash|
instruction, wire = row.split(' -> ')
hash[wire] = Instruction.new(instruction)
end
a_signal = wires.map { |wire, instruction| [wire, instruction.signal(wires)] }.sort.to_h.fetch('a')
wires = input.each_with_object({}) do |row, hash|
instruction, wire = row.split(' -> ')
hash[wire] = Instruction.new(instruction)
end
wires['b'] = Instruction.new(a_signal.to_s)
wires.map { |wire, instruction| [wire, instruction.signal(wires)] }.sort.to_h.fetch('a')
end
class Instruction
def initialize(text)
@text = text
@not, @first, @operation, @second = text.match(
/\A((?<not>NOT) )?(?<first>[a-z0-9]+)( (?<operation>AND|OR|LSHIFT|RSHIFT) (?<second>[a-z0-9]+))?\z/
).captures
@signal = nil
end
def signal(wires)
@signal ||= process(wires)
end
private
def process(wires)
return process_wire(@first, wires).bitwise_complement if @not
return process_wire(@first, wires) if @operation.nil?
case @operation
when "AND"
process_wire(@first, wires) & process_wire(@second, wires)
when "OR"
process_wire(@first, wires) | process_wire(@second, wires)
when "LSHIFT"
process_wire(@first, wires) << process_wire(@second, wires)
when "RSHIFT"
process_wire(@first, wires) >> process_wire(@second, wires)
end
end
def process_wire(value, wires)
return value.to_i if value.match?(/\A[0-9]+\z/)
wires[value].signal(wires)
end
end
end
Day07.run