aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/08/solver.lisp
blob: e3b63e5818c1440ca5bda72d55ff2083489e0714 (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
(ql:quickload '(fiveam uiop))

(defun coord (width height)
  (lambda (x y)
    (when (and (< -1 x width)
               (< -1 y height))
      (+ x (* y width)))))

(let* ((data (uiop:read-file-lines "input"))
       (width (length (car data)))
       (height (length data))
       (forest-arr
         (apply #'vector
                (mapcan (lambda (row)
                          (map 'list (lambda (x) (- (char-code x) 48)) row)) data)))
       (visibility-mask (make-array (* width height) :initial-element nil))
       (location (coord width height)))
  (dotimes (y height)
    ;; left watch
    (loop
      for x from 0 below width
      for maxh = -1 then (max maxh tree-height)
      for tree-height = (aref forest-arr (funcall location x y))
      when (> tree-height maxh)
        do (setf (aref visibility-mask (funcall location x y)) t))
    ;; right watch
    (loop
      for x downfrom (1- width) to 0
      for maxh = -1 then (max maxh tree-height)
      for tree-height = (aref forest-arr (funcall location x y))
      when (> tree-height maxh)
        do (setf (aref visibility-mask (funcall location x y)) t)))

  (dotimes (x width)
    ;; top watch
    (loop
      for y from 0 below height
      for maxh = -1 then (max maxh tree-height)
      for tree-height = (aref forest-arr (funcall location x y))
      when (> tree-height maxh)
        do (setf (aref visibility-mask (funcall location x y)) t))
    ;; bottom watch
    (loop
      for y downfrom (1- height) to 0
      for maxh = -1 then (max maxh tree-height)
      for tree-height = (aref forest-arr (funcall location x y))
      when (> tree-height maxh)
        do (setf (aref visibility-mask (funcall location x y)) t)))

  (loop for v across visibility-mask counting v))