80 lines
1.2 KiB
Ruby
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
|