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[1]
op = match[2]
value = match[3]
condition = match[4]
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
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[1]
op = match[2]
value = match[3]
condition = match[4]
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