(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))