aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/08/solver.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'AoC2022/08/solver.lisp')
-rw-r--r--AoC2022/08/solver.lisp91
1 files changed, 59 insertions, 32 deletions
diff --git a/AoC2022/08/solver.lisp b/AoC2022/08/solver.lisp
index 9031e19..3cab1c0 100644
--- a/AoC2022/08/solver.lisp
+++ b/AoC2022/08/solver.lisp
@@ -11,35 +11,62 @@
(lambda (y x)
(funcall xminor x y))))
-(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-x (coord-x-minor width height))
- (location-y (coord-y-minor width height))
- )
- (flet ((toggle-visibility (major minor location reverse)
- (dotimes (m major)
- (let ((range (loop for i below minor collect i)))
- (loop
- for n in (if reverse (nreverse range) range)
- for maxh = -1 then (max maxh tree-height)
- for tree-height = (aref forest-arr (funcall location n m))
- when (> tree-height maxh)
- do (setf (aref visibility-mask (funcall location n m)) t))))))
- (toggle-visibility height width location-x nil)
- (toggle-visibility height width location-x t)
- (toggle-visibility width height location-y nil)
- (toggle-visibility width height location-y t)
- )
-
-
-
-
- (loop for v across visibility-mask counting v)
- ;; visibility-mask
- )
+(defun flatten-data (data)
+ (apply #'vector
+ (mapcan (lambda (row)
+ (map 'list (lambda (x) (- (char-code x) 48)) row)) data)))
+
+(defun forest (data)
+ (let ((width (length (car data)))
+ (height (length data)))
+ (values (flatten-data data) width height)))
+
+(defun solver-p1 (filename)
+ (multiple-value-bind (forest-arr width height) (forest (uiop:read-file-lines filename))
+ (let ((visibility-mask (make-array (* width height) :initial-element nil))
+ (location-x (coord-x-minor width height))
+ (location-y (coord-y-minor width height)))
+ (flet ((toggle-visibility (major minor location reverse)
+ (let ((range (if reverse
+ (loop for i downfrom (1- minor) to 0 collect i)
+ (loop for i below minor collect i))))
+ (dotimes (m major)
+ (loop
+ for n in range
+ for maxh = -1 then (max maxh tree-height)
+ for tree-height = (aref forest-arr (funcall location n m))
+ when (> tree-height maxh)
+ do (setf (aref visibility-mask (funcall location n m)) t))))))
+ (toggle-visibility height width location-x nil)
+ (toggle-visibility height width location-x t)
+ (toggle-visibility width height location-y nil)
+ (toggle-visibility width height location-y t))
+ (loop for v across visibility-mask counting v))))
+
+(defun solver-p2 (filename)
+ (multiple-value-bind (forest-arr width height) (forest (uiop:read-file-lines filename))
+ (let ((score (make-array (* width height)))
+ (location-x (coord-x-minor width height)))
+
+ (flet ((score-direction (base dir)
+ (loop for l in dir
+ for tree-height = (aref forest-arr l)
+ count l until (>= tree-height base))))
+ (dotimes (y height)
+ (dotimes (x width)
+ (let ((base (aref forest-arr (funcall location-x x y))))
+ (setf (aref score (funcall location-x x y))
+ (*
+ (score-direction base (loop for l from (1+ x) below width collect (funcall location-x l y))) ;; to right
+ (score-direction base (loop for l from (1+ y) below height collect (funcall location-x x l))) ;; to bottom
+ (score-direction base (loop for l downfrom (1- x) to 0 collect (funcall location-x l y))) ;; to left
+ (score-direction base (loop for l downfrom (1- y) to 0 collect (funcall location-x x l)))))))) ;; to top
+ (loop for v across score maximize v)))))
+
+(fiveam:test solutions
+ (fiveam:is (= 21 (solver-p1 "eg-in")))
+ (fiveam:is (= 1672 (solver-p1 "input")))
+ (fiveam:is (= 8 (solver-p2 "eg-in")))
+ (fiveam:is (= 327180 (solver-p2 "input"))))
+
+(fiveam:run-all-tests)