(defun read-maps (filespec) (with-open-file (stream filespec) (loop for line = (read-line stream nil) while line collect (loop collect line while (setf line (read-line stream nil)) while (> (length line) 0))))) (defun count-diff (list1 list2) (loop for string1 in list1 for string2 in list2 sum (loop for c1 across string1 for c2 across string2 sum (if (equal c1 c2) 0 1)))) (defun find-horizontal-mirror (map &optional (ndiff 0)) (loop for prev = () then (cons (car rem) prev) for rem on map for i upto (length map) if (and prev rem (= ndiff (count-diff prev rem))) return i)) (defun rotate-map (map) (loop for i below (length (first map)) collect (coerce (loop for line in map collect (aref line i)) '(string)))) (defun find-vertical-mirror (map &optional (ndiff 0)) (find-horizontal-mirror (rotate-map map) ndiff)) (defun solve (filespec &optional (ndiff 0)) (let ((maps (read-maps filespec))) (loop for map in maps as aux = (find-horizontal-mirror map ndiff) if aux sum (* 100 aux) else sum (find-vertical-mirror map ndiff)))) (defun solve1 (filespec) (solve filespec)) (defun solve2 (filespec) (solve filespec 1)) (print (solve1 "data/13/example.txt")) ;; 405 (print (solve1 "data/13/input.txt")) ;; 30535 (print (solve2 "data/13/example.txt")) ;; 400 (print (solve2 "data/13/input.txt")) ;; 30844