Welcome to Day 10 of my series of Advent of Code solutions in MiniScript! In this challenge, we are tasked with figuring out the display produced by a sort of mini-CPU executing noop
and addx
instructions.
In the first part of the challenge, we need only keep track of the cycle count and the X register, check the product of these on certain cycles, and report the sum of those products. My starter program actually came in useful today, as processing the input (a series of CPU instructions) line-by-line was the sensible thing to do.
My MiniScript program for Part A looks like this:
import "stringUtil"
import "listUtil"
if 1 then fname = "input.txt" else fname = "example.txt"
f = file.open(fname)
x = 1
cycle = 1
resultA = []
checkCycle = function
if [20,60,100,140,180,220].contains(cycle) then
print "Cycle " + cycle + ", x: " + x + " --> " + cycle*x
resultA.push x * cycle
end if
end function
while not f.atEnd
line = f.readLine
if line == null then break // end of file
checkCycle
if line.startsWith("noop") then
cycle = cycle + 1
else if line.startsWith("addx") then
cycle = cycle + 1
checkCycle
cycle = cycle + 1
x = x + val(line.split(" ")[1])
end if
end while
f.close
print "final answer (part A): " + resultA.sum
Nothing super tricky here; the checkCycle
function checks whether the cycle is one of the ones of interest, and if so, prints out the cycle number, X value, and their product, and also pushes that product onto our resultA
list. The main loop checks for the two instructions, updating cycle
and x
accordingly; and after the loop, we print the sum of products saved in resultA
. For my input file, all this generates this output:
Cycle 20, x: 12 --> 240
Cycle 60, x: 4 --> 240
Cycle 100, x: 39 --> 3900
Cycle 140, x: 22 --> 3080
Cycle 180, x: 17 --> 3060
Cycle 220, x: 21 --> 4620
final answer (part A): 15140
Part B
In the second part of the challenge, it is revealed that the CPU uses the cycle number and X value to draw an image on the screen. The display "beam" starts at top-left and moves right 1 space on each cycle, going to the next line every 40 cycles. If the value of X is within 1 of the beam position, it draws the pixel on (#
); otherwise it draws it off (.
).
This mostly required changing only the checkCycle
function, which was already being called by the main loop in all the right places. As I was doing this in Mini Micro, I decided to clear out text.delimiter
so that I could just print a character on each cycle (and then print a char(13)
to force a line break every 40 cycles).
Here's the program for this part of the challenge. (After completing the task, I went back and added the text.color
assignments to make the on pixels really pop.)
import "stringUtil"
import "listUtil"
if 1 then fname = "input.txt" else fname = "example.txt"
f = file.open(fname)
x = 1
cycle = 1
clear
text.delimiter = ""
checkCycle = function
if (cycle-1) % 40 == 0 then print char(13)
col = text.column
if abs(x-col) <= 1 then
text.color = color.orange
print "#"
else
text.color = color.gray
print "."
end if
end function
while not f.atEnd
line = f.readLine
if line == null then break // end of file
checkCycle
if line.startsWith("noop") then
cycle = cycle + 1
else if line.startsWith("addx") then
cycle = cycle + 1
checkCycle
cycle = cycle + 1
x = x + val(line.split(" ")[1])
end if
end while
f.close
text.delimiter = char(13)
When run on my input file, it produced this output:
BPJAZGAP! That was the string I had to type into the challenge page to complete the task.
Though I had a couple of off-by-one errors in the development of each part, I found these on the example data, and they didn't take too long to fix. Part A took about 6 minutes, finishing 262nd; and Part A+B together took about 14 minutes, placing 183rd. My best ranking yet! Will I ever break rank 100 and earn some points in the overall contest? I don't know, but I know that I'm having fun, and MiniScript is handling these tasks like a champ!