# Advent of Code 2017, Day 8: I Heard You Like Registers

## Part A

On Day 8 we need to implement simple CPU performing two instructions on registers. They look like this:

``````b inc 5 if a > 1
a inc 1 if b < 5
c dec -10 if a >= 1
c inc -20 if c == 10
``````

We have register, operation type, amount and condition. Our task is to tell what is the largest value in any register.

``````data = File.readlines("8.txt", chomp: true)
assignments = []
operations = []
variables = []

data.each do |line|
match = line.match(/\A([a-z]+) (inc|dec) (-?\d+) (.+)\z/)
name = match
op = match
value = match
condition = match

variables.push(name)
assignments.push("#{name} = 0")

if op == "inc"
operations.push("#{name} += #{value} #{condition}")
else
operations.push("#{name} -= #{value} #{condition}")
end
end

code = (assignments + operations).join("\n")
code += "\nputs [#{variables.join(", ")}].max"
eval(code)
``````

We can use Ruby eval for that to save on code for parsing conditions. The above code is parsing our input and builds assignments and increase/decrease operations. At the end we add one more line to display the maximum value from all registers.

For the example code we will build the following Ruby code:

``````b = 0
a = 0
c = 0
c = 0
b += 5 if a > 1
a += 1 if b < 5
c -= -10 if a >= 1
c += -20 if c == 10
puts [b, a, c, c].max
``````

## Part B

In the second part we need to tell what is the highest value every held in any register, not at the end of the program.

We need to slighly modify solution from the first part.

``````data = File.readlines("8.txt", chomp: true)
assignments = []
operations = []
variables = []

data.each do |line|
match = line.match(/\A([a-z]+) (inc|dec) (-?\d+) (.+)\z/)
name = match
op = match
value = match
condition = match

variables.push(name)
assignments.push("#{name} = 0")

if op == "inc"
operations.push("#{name} += #{value} #{condition}")
else
operations.push("#{name} -= #{value} #{condition}")
end

operations.push("max = #{name} if #{name} > max")
end

code = ["max = -Float::INFINITY"]
code += assignments
code += operations
code += ["puts max"]

code = code.join("\n")
eval(code)
``````

We added additional line to our code, to store current maximum value. Now generated code for eval will look like this:

``````max = -Float::INFINITY
b = 0
a = 0
c = 0
c = 0
b += 5 if a > 1
max = b if b > max
a += 1 if b < 5
max = a if a > max
c -= -10 if a >= 1
max = c if c > max
c += -20 if c == 10
max = c if c > max
puts max
``````