Advent of Code (in MiniScript), Day 10

JoeStrout - Dec 10 '22 - - Dev Community

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

When run on my input file, it produced this output:

Screen shot of display showing BPJAZGAP in block letters

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!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .