aoc_omni/ruby/2019/2/lib/intcode.rb
2025-12-05 20:34:09 -05:00

80 lines
1.2 KiB
Ruby

class Intcode
attr_reader :memory, :pc, :stopped
def initialize(memory)
@initial_memory = memory
@memory = memory.clone
@pc = 0
@stopped = true
end
def self.for(string)
new string.split(",").map(&:to_i)
end
def run!
@stopped = false
@pc = 0
step! until stopped
end
def reset!
@memory = @initial_memory.clone
@pc = 0
end
def step!
case instruction
when 1
add!
when 2
multiply!
when 99
halt!
else
raise "invalid instuction #{instruction} at #{pc}"
end
end
def add!
v1 = peek(peek(pc + 1))
v2 = peek(peek(pc + 2))
log "adding #{v1} and #{v2}"
poke(peek(pc + 3), v1 + v2)
@pc += 4
end
def multiply!
v1 = peek(peek(pc + 1))
v2 = peek(peek(pc + 2))
log "multiplying #{v1} and #{v2}"
poke(peek(pc + 3), v1 * v2)
@pc += 4
end
def halt!
log "halting!"
@stopped = true
end
def instruction
peek pc
end
def peek(address)
memory[address]
end
def poke(address, value)
log "poking #{value} into #{address}"
memory[address] = value
end
def log(message)
puts message if logging?
end
def logging?
false
end
end