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

• Racket: Having a function to produce `combinations` in the standard library made it pretty easy.
• Common Lisp: Writing a function to enumerate two-item combinations for part 1 was easy; three-item combinations for part 2 was trickier, and I ended up just doing all three-element permutations instead.

## 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.

• Racket

## Day 3

Julia’s strong array support came in helpful here.

### Extra Credit

• Common Lisp: `loop` really shined here, especially the way parallel counters work. Looping over the tree map was very easy and clear:
``````(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

• Common Lisp: I experimented with `struct`, it went ok. Parsing fields seemed a bit awkward, probably room for improvement there.

## 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.