diff options
Diffstat (limited to 'users/tazjin/aoc2023/day3.el')
-rw-r--r-- | users/tazjin/aoc2023/day3.el | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/users/tazjin/aoc2023/day3.el b/users/tazjin/aoc2023/day3.el new file mode 100644 index 000000000000..dd39c1b836d3 --- /dev/null +++ b/users/tazjin/aoc2023/day3.el @@ -0,0 +1,110 @@ +(defun aoc23d3-symbol-p (c) + (not (or (= c ? ) + (and (>= c ?0) + (<= c ?9))))) + +(defun rectangle-for-bounds (bounds) + (let* ((start (save-excursion + (goto-char (car bounds)) + (let ((col (current-column))) + (forward-line -1) + (move-to-column (max 0 (1- col)))) + (point))) + (end (save-excursion + (goto-char (cdr bounds)) + (let ((col (current-column))) + (forward-line 1) + (move-to-column (1+ col))) + (point)))) + (list start end))) + +(defun get-machine-part () + (interactive) + (when-let* ((num-raw (number-at-point)) + (num (abs num-raw)) + ;; handles negative number edge case (bounds contain the `-') + (bounds-raw (bounds-of-thing-at-point 'number)) + (bounds (if (< num-raw 0) + (cons (1- (car bounds-raw)) (cdr bounds-raw)) + bounds-raw)) + (rectangle (rectangle-for-bounds bounds)) + (neighbours (apply #'concat + (apply #'extract-rectangle rectangle)))) + (if (-any #'aoc23d3-symbol-p (string-to-list neighbours)) + (cons num rectangle) + (cons nil rectangle)))) + + +(defun find-machine-parts (input) + (with-temp-buffer + (insert input) + (goto-char (point-min)) + (save-excursion + (replace-string "." " ")) + + (cl-loop while (forward-word) + for result = (get-machine-part) + when (car result) collect (car result)))) + + +;; debugging + +(defvar aoc23d3-example "467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598..") + +(defvar aoc23d3-example2 "12.......*.. ++.........34 +.......-12.. +..78........ +..*....60... +78.......... +.......23... +....90*12... +............ +2.2......12. +.*.........* +1.1.......56") + +(defvar aoc23d3-example3 "243. +..*. +....") + +(defun aoc23d3-debug (p) + "Interactive debugger for the solution, can be bound to a key in +an input buffer. Dots should already have been replaced with +spaces." + (interactive "P") + (unless p + (goto-char aoc23d3-last)) + (rectangle-mark-mode 1) + (forward-word) + (setq aoc23d3-last (point)) + (pcase (get-machine-part) + (`(nil ,b ,e) (progn (set-mark b) + (goto-char e) + (set-face-attribute 'region nil :background "#FAA0A0"))) + (`(,num ,b ,e) (progn (set-mark b) + (goto-char e) + (set-face-attribute 'region nil :background "#d1ffbd"))) + (other (deactivate-mark)))) + +(cl-assert (= 4361 (-sum (find-machine-parts aoc23d3-example))) nil + "example from website is working") + +(cl-assert (= 413 (-sum (find-machine-parts aoc23d3-example2))) nil + "example from subreddit is working") + +(cl-assert (= 243 (-sum (find-machine-parts aoc23d3-example3))) nil + "example from telegram is working") + +;; day 1 (incomplete) + +(-sum (find-machine-parts (s-trim (f-read "~/Downloads/input.txt")))) |