Advent of Code 2022: Day 10

This challenge needs a bit of care with the logic for displaying the output and deciding when to calculate the phase.

Final Program

procedure main(inputs)
  local filename

  if *inputs = 1 then {
    filename := inputs[1]

    # Part 1 solution
    write("Part 1: ", run_program(filename))
    # Part 2 solution is displayed
  } else {
    write("Provide a filename of data")
  }
end

# Checks if phased should be calculated for given cycle,
# and returns value, if so.
procedure phase_for(x, cycle)
  if cycle = 20 | (cycle-20)%40 = 0 then
    return x * cycle
  else
    return 0
end

# Output display
procedure output_display(x, cycle)
  local pixel

  pixel := (cycle-1) % 40 # row value, 0 to 39
  if (x-pixel) = (-1|0|1) then # check if pixel is in sprite
    writes("#")
  else
    writes(".")
  if pixel = 39 then write() # newline
end

procedure run_program(filename)
  local file
  local cycle, instr, phase, x

  file := open(filename) | stop("Cannot open ", filename)
  x := 1
  cycle := 1
  phase := 0
  every instr := !file do {
    output_display(x, cycle)              # output display on each cycle
    instr ? {
      if ="noop" then {
        cycle +:= 1
        phase +:= phase_for(x, cycle)
      } else if ="addx " then {
        cycle +:= 1
        phase +:= phase_for(x, cycle)
        output_display(x, cycle)          # make sure intermediate cycle displayed
        cycle +:= 1
        x +:= integer(tab(0))
        phase +:= phase_for(x, cycle)
      } else
        stop("Error in processing input")
    }
  }
  close(file)

  return phase
end

Page from Peter's Scrapbook, output from a VimWiki on 2024-01-29.