(ql:quickload '(fiveam)) (defparameter eg-vert "#...##..# #....#..# ..##..### #####.##. #####.##. ..##..### #....#..#") (defparameter eg-horizontal "#.##..##. ..#.##.#. ##......# ##......# ..#.##.#. ..##..##. #.#.##.#.") (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 find-v-mirror (rows) (remove-if-not (lambda (n) (v-mirror-p rows n)) (find-repeat rows))) (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 transpose-rows (rows) (arrows:-<> rows (mapcar #'string-to-octets <>) (apply #'map 'list (lambda (&rest vals) (coerce (mapcar #'code-char vals) 'string)) <>))) (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)))) (fiveam:is (equal '(3) (find-repeat (cl-ppcre:split "\\n" eg-horizontal)))) (fiveam:is (null (find-v-mirror (cl-ppcre:split "\\n" eg-horizontal)))) (fiveam:is (equal '(5) (find-h-mirror (cl-ppcre:split "\\n" eg-horizontal))))) (defun solver (maps) (let ((verical-mirrors (delete nil (mapcan #'find-v-mirror maps))) (horizontal-mirrors (delete nil (mapcan #'find-h-mirror maps)))) (+ (* 100 (apply #'+ verical-mirrors)) (apply #'+ horizontal-mirrors)))) (defun parse-input (file) (arrows:->> (uiop:read-file-string file) (cl-ppcre:split "\\n\\n") (mapcar (lambda (map) (cl-ppcre:split "\\n" map))))) (fiveam:test solutions (fiveam:is (= 405 (solver (parse-input "eg-in")))) (fiveam:is (= 35360 (solver (parse-input "input"))))) (fiveam:run!)