Thread to post Advent of Code solutions and discussions around them. For day 1 I am pretty happy with most of my solution, except that I have this function:
I gave up on figuring out a formula for part 2 based on integer division after a few failed attempts and ended up just simulating turning the dial a click at a time via brute force. I'm not proud but it worked.
Not shown: Parsing the input into a list of numbers (R50 -> 50, L12 -> -12, etc.), and the definition of that anaphoric acase macro, which I tossed in because I wanted at least something clever.
I used Common Lisp instead of Racket for today's problem, but the equivalents to some things I did in it:
string= from the srfi/13 string library lets you compare sections of strings, avoiding the need for substring and saving the garbage collector from a lot of extra work.
The maximum length of a string representation of the numbers in the puzzle input is something like 10 characters. For part 2, it's trivial to create a pre-defined set of possible lengths of subsequences of the strings and use them instead of always looping through a range and repeatedly figuring out which numbers work. For example, an 8 digit number can have subsequences of length 1, 2 or 4. I just had a vector of lists of those lengths and only checked against the appropriate one ((for/or ([len (in-list (vector-ref groupings (string-length num)))]) (repeats-length-n? num len))).
Relied heavily on mutable sets for day four. For those "graphical" problems I often find the most sane (but perhaps not the most efficient) structure is just keeping a "bag of coordinates."
For example, reading the file is:
(define size
(for/last ([row (file->lines "input")]
[y (in-naturals)])
(for/last ([c row]
[x (in-naturals)])
(when (equal? c #\@)
(set-add! diag (cons x y)))
(cons x y))))
The operation of removing rolls wasn't pretty, though... I relied on a couple globals for counting the number of removed items and for signaling when no further items could be removed:
I really wanted a better signaling mechanism there. I wonder if there is a more idiomatic way of doing it. I think if I used immutable sets I probably could integrate it in the recursion by comparing the old set and new set directly, but with mutable sets I am not sure.