class Assembunny attr_accessor :a, :b, :c, :d, :pc, :program def initialize(program) @a = 0 @b = 0 @c = 0 @d = 0 @pc = 0 @program = program end def current_instruction program[pc] end def execute_current_instruction execute_instruction current_instruction end def execute_instruction(instruction) send("exec_#{instruction.split.first}", *instruction.split[1..]) end def increment_pc @pc = @pc + 1 end def exec_cpy(from, to) if from.to_i != 0 send("#{to}=", from.to_i) else send("#{to}=", send("#{from}")) end increment_pc end def exec_inc(reg) send("#{reg}=", send("#{reg}").to_i + 1) increment_pc end def exec_dec(reg) send("#{reg}=", send("#{reg}").to_i - 1) increment_pc end def exec_jnz(predicate, to) predicate = send("#{predicate}") if predicate.to_i.zero? if predicate.to_i.zero? increment_pc else @pc += to.to_i end end def halts? @pc >= program.length end end input = STDIN.read.chomp instructions = input.split("\n") computer = Assembunny.new(instructions) computer.execute_current_instruction until computer.halts? part_1 = computer.a puts "Part 1: #{part_1}" computer = Assembunny.new(instructions) computer.c = 1 computer.execute_current_instruction until computer.halts? part_2 = computer.a puts "Part 2: #{part_2}"