For day 13, we're asked to find the solutions to some linear
equations. We use the cl-ppcre
library to parse the
equations and then use Cramer’s rule to solve them.
;;; -*- Lisp -*- (in-package "ADVENT2024/DAY13") ;; Cramers Rule to solve Ax + By = M, Cx + Dy = N ;; x = (MD - BN) / (AD - BC) ;; y = (AN - MC) / (AD - BC) (defun cramers-rule (A B C D M N) (let ((det (- (* A D) (* B C)))) (if (= det 0) nil (values (/ (- (* M D) (* B N)) det) (/ (- (* A N) (* M C)) det)))))
The input is in blocks of three lines with a fourth blank line
between them. We parse the input with a regular expressions and
then apply cramers-rule
to solve the equations. The
conversion factor is a delta that is added to the coordinates of the
target.
(defun puzzle (pathname &optional (conversion 0)) (collect-sum (multiple-value-bind (line1 line2 line3 line4) (chunk 4 4 (catenate (scan-file pathname #’read-line) (scan ’list ’("")))) ;; extra blank line at end (#M(lambda (line1 line2 line3) (cl-ppcre:register-groups-bind ((#’parse-integer ax) (#’parse-integer ay)) ("Button A: X\\+(\\d+), Y\\+(\\d+)" line1) (cl-ppcre:register-groups-bind ((#’parse-integer bx) (#’parse-integer by)) ("Button B: X\\+(\\d+), Y\\+(\\d+)" line2) (cl-ppcre:register-groups-bind ((#’parse-integer px) (#’parse-integer py)) ("Prize: X\\=(\\d+), Y\\=(\\d+)" line3) (multiple-value-bind (x y) (cramers-rule ax bx ay by (+ px conversion) (+ py conversion)) (if (and x y (>= x 0) (>= y 0) (integerp x) (integerp y)) (+ (* x 3) y) 0)))))) line1 line2 line3)))) (defun part-1 () (puzzle (input-pathname))) (defun part-2 () (puzzle (input-pathname) (expt 10 13)))
No comments:
Post a Comment