diff options
-rw-r--r-- | AoC2023/day13/solver.lisp | 85 |
1 files changed, 47 insertions, 38 deletions
diff --git a/AoC2023/day13/solver.lisp b/AoC2023/day13/solver.lisp index f149f2e..53cc753 100644 --- a/AoC2023/day13/solver.lisp +++ b/AoC2023/day13/solver.lisp @@ -1,4 +1,7 @@ -(ql:quickload '(fiveam)) +;; 6:34 +;; 8:11 part 1 +;; 9:36 part 2 +(ql:quickload '(fiveam arrows cl-ppcre)) (defparameter eg-vert "#...##..# #....#..# @@ -16,26 +19,24 @@ ..##..##. #.#.##.#.") -(defun find-repeat (rows) - (loop for (one two-or-nil) on rows by #'cdr - for idx from 0 - when (and (not (null two-or-nil)) - (equal one two-or-nil)) - collect (1+ idx))) +(defun count-differences (a b) + (loop for x across a + for y across (or b "") + count (not (eq x y)))) -(defun find-v-mirror (rows) - (remove-if-not (lambda (n) (v-mirror-p rows n)) - (find-repeat rows))) +(defun v-mirror (rows &optional (max-differences 0)) + (loop + for idx from 1 below (length rows) + when + (= max-differences + (loop + for above in (reverse (subseq rows 0 idx)) + for below in (subseq rows idx) + sum (count-differences above below))) + do (return idx))) -(defun v-mirror-p (rows idx) - (every #'equal - (reverse (subseq rows 0 idx)) - (subseq rows idx))) - - -(defun find-h-mirror (rows) - (find-v-mirror - (transpose-rows rows))) +(defun h-mirror (rows &optional (max-differences 0)) + (v-mirror (transpose-rows rows) max-differences)) (defun transpose-rows (rows) (arrows:-<> @@ -46,30 +47,36 @@ (fiveam:test partials (fiveam:is - (equal '(4) - (find-repeat - (cl-ppcre:split "\\n" eg-vert))))(fiveam:is - (equal '(4) - (find-v-mirror - (cl-ppcre:split "\\n" eg-vert)))) - + (= 4 + (v-mirror + (cl-ppcre:split "\\n" eg-vert)))) (fiveam:is - (equal '(3) - (find-repeat - (cl-ppcre:split "\\n" eg-horizontal)))) + (= 1 + (v-mirror + (cl-ppcre:split "\\n" eg-vert) 1))) (fiveam:is - (null (find-v-mirror + (null (v-mirror (cl-ppcre:split "\\n" eg-horizontal)))) (fiveam:is - (equal '(5) - (find-h-mirror - (cl-ppcre:split "\\n" eg-horizontal))))) + (= 3 (v-mirror + (cl-ppcre:split "\\n" eg-horizontal) 1))) + (fiveam:is + (= 5 + (h-mirror + (cl-ppcre:split "\\n" eg-horizontal)))) + (fiveam:is + (null (h-mirror + (cl-ppcre:split "\\n" eg-horizontal) 1)))) -(defun solver (maps) - (let ((verical-mirrors (delete nil (mapcan #'find-v-mirror maps))) - (horizontal-mirrors (delete nil (mapcan #'find-h-mirror maps)))) +(defun solver (maps &optional (max-differences 0)) + (let ((vertical-mirrors (delete nil (mapcar (lambda (m) + (v-mirror m max-differences)) + maps))) + (horizontal-mirrors (delete nil (mapcar (lambda (m) + (h-mirror m max-differences)) + maps)))) (+ - (* 100 (apply #'+ verical-mirrors)) + (* 100 (apply #'+ vertical-mirrors)) (apply #'+ horizontal-mirrors)))) (defun parse-input (file) @@ -80,6 +87,8 @@ (fiveam:test solutions (fiveam:is (= 405 (solver (parse-input "eg-in")))) - (fiveam:is (= 35360 (solver (parse-input "input"))))) + (fiveam:is (= 400 (solver (parse-input "eg-in") 1))) + (fiveam:is (= 35360 (solver (parse-input "input")))) + (fiveam:is (= 36755 (solver (parse-input "input") 1)))) (fiveam:run!) |