🎄⌨️ Advent of Code 2018

Tech-note 46fcfd

Today’s problems pretty clearly called for the use of a two-dimensional array, or a matrix or whatever you like to call it. The LISPy way to do these is to think of the 2D array as a list of lists, but I pretty quickly got annoyed with Racket here.

(define fabric (make-vector 5 (make-vector 5 0)))
(define (poke-square x y val) 
    (vector-set! (vector-ref fabric y) x val))

(poke-square 1 2 9)

Contrary to what you might think, this changes the value in position 2 of every row to 9. This is because make-vector fills fabric not with unique vectors but with identical references to a single vector.

Racket does have a math package with functions for arrays and matrices but even these are cumbersome for the simple operation of fingering an individual bit somewhere in the middle. There is furthermore a warning at the top of the docs for each that using these libraries without using Typed Racket is 50⨉ slower. I didn’t feel like learning Typed Racket today.

I’m biting my tongue about how annoying it is that simple, native 2-D array support is MIA from such an advanced language, because invariably as soon as I say something somebody will point out something simple and perfect that I missed. (But when that happens, it’ll still be Racket’s fault that it took so long to find.)

Just use pixels already

My solution

At any rate I decided to find the solution graphically, by drawing on a canvas using a semi-opaque brush. After drawing all the rectangles, you can then go back and read the alpha channel values for each pixel to find those that have been drawn over more than once.

This isn’t particularly fast. The solution for part 1 takes 10.8 seconds on my MacBook Pro, and the solution for part 2 takes 1.8 seconds. But it has the benefit of giving me, “for free”, a graphical representation of the inputs (and the Part 2 solution highlighted in red):

Graphic representation of my input and part 2 answer