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