Advent of Code 2023 - Day 3, Part 1 ¶
A classic, buffer-based implementation this time
I made it! I woke up early, drank 3 coffees, but in the end, I managed to solve the puzzle and post the solution before the others! 🙂
The puzzle this time is about extracting numbers from a 2D array of characters and checking whether the number neighbours any character other than a dot (".").
In Emacs, all text is in a 2D array by default - that's (conceptually) what a buffer is, after all. So there's really not much to the solution this time, other than handling some corner cases (first and last lines, and treating newlines as dots - for numbers that are at the end of the line).
Here's the solution:
1: ;; NOTE: lines are 140 characters wide (maybe verify this instead of assuming?) 2: (with-current-buffer (get-buffer "input3.txt") 3: (goto-char (point-min)) 4: (let (numbers (lines (count-lines (point-min) (point-max)))) 5: (while (re-search-forward (rx (1+ num)) nil t) 6: (let* ((beg (match-beginning 0)) 7: (end (match-end 0)) 8: (surrounding (concat 9: (string (char-after (1- beg))) ; preceding char 10: (string (char-after end)) ; following char 11: ;; previous line 12: (if (not (= 1 (line-number-at-pos))) 13: (buffer-substring-no-properties (- beg 142) (- end 140)) 14: ".") 15: ;; next line 16: (if (not (= lines (line-number-at-pos))) 17: (buffer-substring-no-properties (+ beg 140) (+ end 142)) 18: ".")))) 19: (unless (cl-every (lambda (c) (or (eq c ?\n) (eq c ?.))) surrounding) 20: (push (string-to-number (match-string 0)) numbers)))) 21: (apply #'+ numbers)))
507214
We just loop through the numbers in the buffer, fetch the characters that surround the number, and verify there are only dots (and newlines, as a special case) in these characters.
I thought about using save-excursion
and forward-line
to get the preceding
and following lines, then using looking-at-p
to check for symbols - I think it
would work and I wouldn't need to check line width in that case. By the time I
thought of it, though, buffer-substring
-based solution worked already, so I
just left it as is.
Unfortunately, I don't have the time to solve Part 2 of the puzzle. In part 2,
you need to find all *
symbols that have more than one number in its
surroundings. It's more interesting than Part 1 because there are more ways of
solving it. I'll see if I have the time to code the solution in the evening.