Code for the Advent of Code event
aoc
advent-of-code
1#!/usr/bin/env ruby
2# frozen_string_literal: true
3
4class CPU
5 def initialize(instructions)
6 @regs = {
7 a: 0,
8 b: 0,
9 c: 0,
10 d: 0
11 }
12
13 @instructions = instructions
14 @pc = 0
15 end
16
17 def self.number?(arg)
18 arg =~ /^\d+$/
19 end
20
21 def step!
22 return false if @pc == @instructions.size
23 instruction = @instructions[@pc]
24 # puts '%2d %10s [%s]' % [@pc, instruction.join(' '), dump_regs.join(' ')]
25 send(*instruction)
26 @pc += 1
27 true
28 end
29
30 def [](reg)
31 @regs[reg]
32 end
33
34 def []=(reg, value)
35 @regs[reg] = value.to_i
36 end
37
38 def cpy(source, destination)
39 if self.class.number? source # rubocop:disable Style/ConditionalAssignment
40 self[destination.to_sym] = source
41 else
42 self[destination.to_sym] = self[source.to_sym]
43 end
44 end
45
46 def inc(register)
47 self[register.to_sym] += 1
48 end
49
50 def dec(register)
51 self[register.to_sym] -= 1
52 end
53
54 def jnz(register, target)
55 value = self.class.number?(register) ? register : self[register.to_sym]
56 return if value == 0
57 @pc += target.to_i - 1
58 end
59
60 private
61
62 def dump_regs
63 @regs.map { |_r, v| '%3d' % [v] }
64 end
65end
66
67instructions = $stdin.readlines.map { |line| line.strip.split }
68
69cpu = CPU.new instructions
70
71while cpu.step!; end
72
73puts "(1): #{cpu[:a]}"
74
75cpu = CPU.new instructions.unshift %w[cpy 1 c]
76
77while cpu.step!; end
78
79puts "(2): #{cpu[:a]}"