aoc_omni/ruby/2019/2/main.rb
2025-11-30 21:22:21 -05:00

93 lines
1.6 KiB
Ruby

class Computer
attr_reader :data
def initialize(data)
@data = data
@program_counter = 0
@halted = true
end
def run
@halted = false
while !@halted
instruction_range = data[@program_counter..(@program_counter + 3)]
opcode = OpCode.for(self, *instruction_range)
opcode.execute
@program_counter += 4
end
end
def read(index)
data[index]
end
def write(index, value)
data[index] = value
end
def halt
@halted = true
end
def self.from_string(string)
new(string.split(",").map(&:to_i))
end
def self.from_file(file_path)
from_string(File.read file_path)
end
end
class OpCode
attr_reader :computer
def initialize(computer)
@computer = computer
end
def self.for(computer, *args)
case args[0]
when 1
OpCode1.new(computer, *args[1..])
when 2
OpCode2.new(computer, *args[1..])
when 99
OpCode99.new(computer)
end
end
end
class OpCode1 < OpCode
attr_reader :destination, :first_position, :second_position
def initialize(computer, arg1, arg2, arg3)
super(computer)
@first_position = arg1
@second_position = arg2
@destination = arg3
end
def value_to_write
computer.read(first_position) + computer.read(second_position)
end
def execute
computer.write destination, value_to_write
end
end
class OpCode2 < OpCode1
def value_to_write
computer.read(first_position) * computer.read(second_position)
end
end
class OpCode99 < OpCode
def execute
computer.halt
end
end
c = Computer.from_file("../data/2019/2/input.txt")
c.write(1, 12)
c.write(2, 2)
c.run
puts "Part 1: #{c.read(0)}"