aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2023/day13/solver.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'AoC2023/day13/solver.lisp')
-rw-r--r--AoC2023/day13/solver.lisp85
1 files changed, 85 insertions, 0 deletions
diff --git a/AoC2023/day13/solver.lisp b/AoC2023/day13/solver.lisp
new file mode 100644
index 0000000..f149f2e
--- /dev/null
+++ b/AoC2023/day13/solver.lisp
@@ -0,0 +1,85 @@
+(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!)