aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2023/day13/solver.lisp
blob: f149f2e61aa904096bc7255b3c64edce7ba61539 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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!)