Something went wrong. Try again.
Code for the Advent of Code event
aoc advent-of-code
Something went wrong. Try again.
1.9 kB · 105 lines
Ruby
at rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106#!/usr/bin/env ruby# frozen_string_literal: true
class CPU attr_reader :recovered_frequency, :send_count
def initialize(send_queue = nil, recv_queue = nil) @send_queue = send_queue @recv_queue = recv_queue @registers = Hash.new 0 @pc = 0 @send_count = 0 end
def load(program) @program = program.map(&:split) self end
def run_part1 step while @pc >= 0 && @pc < @program.size && !recovered_frequency self end
def run_part2 @wait = false step while @pc >= 0 && @pc < @program.size && !@wait end
def step instruction = @program[@pc] send(*instruction) @pc += 1 end
def snd(freq) freq = resolve(freq) @last_frequency = freq return unless @send_queue @send_queue.enq freq @send_count += 1 end
def set(reg, value) @registers[reg] = resolve(value) end
def add(reg, value) @registers[reg] += resolve(value) end
def mul(reg, value) @registers[reg] *= resolve(value) end
def mod(reg, value) @registers[reg] %= resolve(value) end
def rcv(value) @recovered_frequency = @last_frequency unless resolve(value) == 0 return if @recv_queue.nil? if @recv_queue.empty? @pc -= 1 @wait = true return end @registers[value] = @recv_queue.deq end
def jgz(value, offset) return if resolve(value) <= 0 @pc += resolve(offset) - 1 end
private
def resolve(value) n = value.to_i n.to_s == value ? n : @registers[value] endend
PROGRAM = ARGF.readlines
puts CPU.new.load(PROGRAM).run_part1.recovered_frequency
a_to_b = Queue.newb_to_a = Queue.new
a = CPU.new(a_to_b, b_to_a).load(PROGRAM)a.set 'p', '0'
b = CPU.new(b_to_a, a_to_b).load(PROGRAM)b.set 'p', '1'
a.run_part2b.run_part2
while !a_to_b.empty? || !b_to_a.empty? a.run_part2 b.run_part2end
puts b.send_count