From a13bd02d72cea60d9218f716a83a2f1bb99500cf Mon Sep 17 00:00:00 2001 From: Oscar Najera Date: Sun, 3 Dec 2023 22:13:57 +0100 Subject: [AoC2023] day02 lisp --- AoC2023/day02/solver.lisp | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 AoC2023/day02/solver.lisp (limited to 'AoC2023/day02/solver.lisp') diff --git a/AoC2023/day02/solver.lisp b/AoC2023/day02/solver.lisp new file mode 100644 index 0000000..60aa3cf --- /dev/null +++ b/AoC2023/day02/solver.lisp @@ -0,0 +1,79 @@ +(ql:quickload '(uiop fiveam cl-ppcre)) +(defparameter eg-input "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green +Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue +Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red +Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red +Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green") + +(defun parse-set (info) + (let (list) + (cl-ppcre:do-register-groups ((#'parse-integer count) (#'read-from-string color)) + ("(\\d+) (blue|red|green)" info) + (push (list color count) list)) + list)) + +(defun in-limits (max-red max-green max-blue) + (lambda (value) + (destructuring-bind (color count) value + (<= count + (ecase color + (red max-red) + (green max-green) + (blue max-blue)))))) + +(defun parse-game (game-bounds) + (lambda (line) + (destructuring-bind (game . sets) + (uiop:split-string line :separator '(#\; #\:)) + (if (every + (lambda (s) + (every game-bounds (parse-set s))) + sets) + (parse-integer (cl-ppcre:scan-to-strings "\\d+" game)) + 0)))) + +(defun game-powers (line) + (apply #'* (mapcar #'cadr (parse-set (cdr (uiop:split-string line :separator '(#\; #\:))))))) + +(defun solve1 (lines bounds) + (reduce + #'+ + lines + :key (parse-game bounds))) + + +(defun max-set (top set) + (loop for (color count) in set do + (let ((var (ecase color + (red 0) + (green 1) + (blue 2)))) + (setf (elt top var) (max (elt top var) count)))) + top) + +(defun solve2 (lines) + (apply #'+ + (mapcar (lambda (line) + (apply #'* + (reduce #'max-set (cdr (uiop:split-string line :separator '(#\; #\:))) + :key #'parse-set + :initial-value (make-list 3 :initial-element 0)))) + lines))) + +(fiveam:test solutions + (fiveam:is + (= 8 + (solve1 + (uiop:split-string eg-input :separator '(#\Newline)) + (in-limits 12 13 14)))) + (fiveam:is + (= 2369 + (solve1 + (uiop:read-file-lines "input") + (in-limits 12 13 14)))) + (fiveam:is + (= 2286 + (solve2 (uiop:split-string eg-input :separator '(#\Newline))))) + (fiveam:is + (= 66363 + (solve2 (uiop:read-file-lines "input"))))) -- cgit v1.2.3