Though I’m not a fanatic participant in Advent of Code I still like to join in on the fun and challenge myself to solve the puzzles posted every day. I’m one of those players that plays whenever there is time, instead of the top players that set their alarm clocks to be at the ready when the assignment gets published.

When I opened up the assignment for this morning I was pleasantly surprised to see yet another one involving our beloved IntCode computer đŸ˜‰ (As Jochem already predicted in his blog)
Today’s challenge involves moving a paint robot around using an IntCode program. There was just another twist. Now the IntCode’s program needed to output to a grid from which it read via the input operation. Fortunately for day 7 part 2 I already had to create a helper function that used a generator as input instead of a fixed set of values so I could easily reuse that again.

The exercise seemed straightforward enough so I implemented my solution quickly, started it up and waited for the output. The program terminated quite rapidly and gave me an answer that seemed reasonable. I submitted the answer and… Answer too high :(. How on earth is that possible!?!? Back to the drawing board… I re-read the entire assignment to make sure I didn’t misinterpret any part of it (which is a common source of mistakes for me to be honest).

Aha I thought, I only need to register when a panel actually changes color. So I rewrote the program to keep track of when a panel changes color. After running the program again I put in the answer and… Answer too low.
How is this even possible!?!? Re-reading the assignment again I see that it is clearly asking for the number of locations that have received paint (of any color) at least once. Time to pull out the big guns. In simple cases you can just add some print() statements to your program to debug what is going on. But whenever things get really complex I prefer to use a debugger. a debugger give you so much more visibility into what is going on in your program when compared to simple print statements. You can see the call stack leading up to your breakpoint, see the variables that are in scope and control the execution of your program in a step by step fashion. So much more insight and the added benefit of not having to clean up all the print() statements you added while tracking the bug down đŸ˜‰

Debugging in VSCode

For daily development I use Visual Studio Code. It has great support for a lot of languages such as Typescript, c#, Java and (important for this competition) python. It also has a nice debugging interface for stepping through the code in case things get messy (such as today).

To debug python code you’ll first need a launch configuration. If you’ve never debugged a python file in a workspace before vs code will help you set it up. Open up the debugger view and hit the cogwheel right next to No configurations. Select “Python file and it will generate the following configuration file for debugging (called launch.json):

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Current File",
      "type": "python",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal"
    }
  ]
}

You can now open the python file you would like to debug, add some breakpoints on the lines you would like to inspect and hit F5 (or press the play button next to the debug configuration) to start the file in debug mode. Speaking of breakpoints, you can even use conditional breakpoints to only pause execution when a certain condition holds. I used that today to pause the execution of my robot program after 2007 iterations (the iteration before it completed in my case) so I could inspect the state of my program right before it completed.

Squashing the bug

Running in debug mode my first suspicion went to my implementation of the turning mechanism of the bot. For some reason I always have a hard time when a puzzle involve angles and this one was no exception. But after getting a piece of paper and writing out all possibilities (there’s only 8) I found out that, against all odds, I got the direction logic correct on the first try.

I turned my attention to the block that was about painting the squares. And then it struck me. Even though I called my boolean turnMode I interpreted it as paintMode which meant it was turning when it should be painting and vice versa :/ ARGGGH! After I flipped the logic I ran the program again and now finally I was rewarded with a gold star.

The second part was another pixel rendering exercise which led to a quick satisfying result:

Now I’ll have to wait for the next window of opportunity to solve more puzzles…