(defpackage #:advent.2024.03 (:use #:cl)) (in-package #:advent.2024.03) (defvar *input* "03.input") ;;; Part 1 ;; parse a file for mul(\d\d?\d?,\d\d?\d?), multiply the numbers, then add the results (defun solve1 () (let ((in (uiop:read-file-string *input*))) (solve1/string in))) (defvar *mul-regex* "mul\\((\\d\\d?\\d?),(\\d\\d?\\d?)\\)") (defun solve1/string (in) (let ((sum 0)) (ppcre:do-scans (ms me rs re "mul\\((\\d\\d?\\d?),(\\d\\d?\\d?)\\)" in sum) ;; (format t "~A/~A || ~A/~A~&" ms me rs re) (let ((a (parse-integer in :start (elt rs 0) :end (elt re 0))) (b (parse-integer in :start (elt rs 1) :end (elt re 1)))) (incf sum (* a b))) sum))) ;;; Part 2 ;; start with mul() enabled; on don't(), disable it; on do(), enable. add only ;; enabled mul()s. (defvar *do-regex* "do\\(\\)") (defvar *dont-regex* "don't\\(\\)") ;; I get to do this the long way round (defun solve2 () (let ((s (uiop:read-file-string *input*))) (solve2/string s))) (defun solve2/string (in) (let ((mulp t) (sum 0)) (cl-ppcre:do-matches-as-strings (m (format nil "~A|~A|~A" *mul-regex* *dont-regex* *do-regex*) in sum) (cond ((and (ppcre:scan *mul-regex* m) mulp) (ppcre:do-register-groups (a b) ; this warning is .. fine??? (*mul-regex* m nil :sharedp t) (incf sum (* (parse-integer a) (parse-integer b))))) ((ppcre:scan *dont-regex* m) (setf mulp nil)) ((ppcre:scan *do-regex* m) (setf mulp t)))) sum))