From 889849613fd6afb6b2d7e6f64a513be3c72fcdf0 Mon Sep 17 00:00:00 2001 From: Oscar Najera Date: Wed, 20 Dec 2023 07:49:53 +0100 Subject: [AoC2023] day19 part 1 lisp --- AoC2023/day19/solver.lisp | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 AoC2023/day19/solver.lisp (limited to 'AoC2023/day19/solver.lisp') diff --git a/AoC2023/day19/solver.lisp b/AoC2023/day19/solver.lisp new file mode 100644 index 0000000..9c2f0a0 --- /dev/null +++ b/AoC2023/day19/solver.lisp @@ -0,0 +1,60 @@ +;;6:51 +;;7:49 +;; +(ql:quickload '(fiveam cl-ppcre arrows)) + +(defstruct part + x m a s) + +(defun part-sum (part) + (with-slots (x m a s) part + (+ x m a s))) + +(defun solve (filename) + (let ((workflows (make-hash-table)) + parts) + (loop for line in (uiop:read-file-lines filename) + do + (cond + ((string-equal line "")) + ((eq #\{ (aref line 0)) + (cl-ppcre:register-groups-bind ((#'parse-integer x m a s)) + ("{x=\(\\d+\),m=\(\\d+\),a=\(\\d+\),s=\(\\d+\)}" line) + (push (make-part :x x :m m :a a :s s) parts))) + ((multiple-value-bind (name rule) (parse-rule line) + (setf (gethash name workflows) rule))))) + (reduce #'+ parts :key (alexandria:curry #'test-part workflows)))) + +(defun parse-tests (line-rule) + (loop for test in (cl-ppcre:split "," line-rule) + collect + (cl-ppcre:register-groups-bind ((#'read-from-string prop op val target)) + ("\(\\w\)\(<|>\)\(\\d+\):\(\\w+\)" test) + (list op prop val target)))) + +(fiveam:test parts + (fiveam:is (equal + '((< S 537 GD) (> X 2440 R)) + (parse-tests "s<537:gd,x>2440:R" )))) + +(fiveam:test solutions + (fiveam:is (= 19114 (solve "eg-in"))) + (fiveam:is (= 446517 (solve "input")))) + +(defun parse-rule (line) + (cl-ppcre:register-groups-bind ((#'read-from-string name) (#'parse-tests tests) (#'read-from-string default)) + ("\(\\w+\){\(.*\),\(\\w+\)}" line) + (values name + (lambda (part) + (or (loop for (op prop val target) in tests + when (funcall op (slot-value part prop) val) + do (return target)) + default))))) + +(defun test-part (workflows part &optional (start 'in)) + (let ((out (funcall (gethash start workflows) part))) + (cond ((eq 'A out) + (part-sum part)) + ((eq 'R out) 0) + ((test-part workflows part out))))) +(fiveam:run!) -- cgit v1.2.3