Advent of Code 2020 is here! This year I’m revisiting Julia, a cross between Python, Fortran, with a hint of Lisp. My solutions are on SourceHut, and in this and follow-up posts I’ll keep a running log of my approach and thoughts (edit: I go into much more detail for later, harder problems).

Day 1

My immediate idea was to take advantage of Julia’s first-class matrix/vector operations. This made quick work of both parts, although as a colleague pointed out to me it could have yielded false positives, since I included each number plus itself (i.e. I really should have filtered out the diagonals).

Extra credit

Day 2

Julia has some nice features I was able to use here, including pipelines (|>), which can also be done per-element (.|>, what Julia calls “broadcasting”). For example, the following nested function calls:

    println(sum(map(x->fn(parseline(x)...), eachline("input/day02.txt"))))

can be rewritten as:

    eachline("input/day02.txt") .|> parseline .|> fn |> sum |> println

In addition to being easier to read, it helps for rapid interactive development and debugging.

Extra Credit

Day 3

Julia’s strong array support came in helpful here.

Extra Credit

(defun trees (m xs ys)
  (loop for j below (array-dimension m 0) by ys
        for i by xs
        count (aref m j (mod i (array-dimension m 1)))))

Notice how no upper limit needs to be set for the column counter i, letting the row counter j solely terminate the loop.

Day 4

Julia has a solid regex library. Also notable, it allows “chained” comparison operators, e.g.

valid_byr(p) = 1920 <= parse(Int,p["byr"]) <= 2002

Extra Credit

Day 5

As they say, there are 10 types of people in the world: those who speak binary, and those who don’t.

Day 6

Julia fully embraces unicode. Sometimes it’s clearer using mathematical symbols, but in general probably not. I like using them anyways, (like how I use λ instead of lambda in racket). It’s nice that the REPL and emacs mode support LaTϵχ commands followed by <tab> to quickly insert them (e.g. \cup -> ∪ for union and \cap -> ∩ for intersection).

Day 7

A naive parser and some regex solved this. Bonus: I had my program output a dot file for graphing in Graphviz, but the output from dot was gigantic and unreadable. I thought maybe circo would make a nice graph, but I gave up on it after about a half hour.

Day 8

Is this the next intcode‽ Maybe not… I invested a bit into learning Julia’s struct and multi-dispath methods just in case.

Day 9

Ugh, I hate when you make an assumption during part one that makes you rewrite a bunch of code for part two. In this case I thought I was clever (“oh, we only need the last n entries? I’ll write a ring buffer!"), but then of course we needed all the entries in part two. Admittedly the code wasn’t really that more complicated just indexing into a Vector, and I got rid of all the probaly-buggy Ring code I’d written. Learned a bit more about methods and multi-dispatch. Did I mention how much I love the [email protected] and @debug macros? Well they’re nice.

Day 10

My Day 10 writeup got a bit long, so I broke it into its own post. I’m going to try to do more detailed write-ups like that going forward.