aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/14
diff options
context:
space:
mode:
Diffstat (limited to 'AoC2022/14')
-rw-r--r--AoC2022/14/solver.lisp63
1 files changed, 36 insertions, 27 deletions
diff --git a/AoC2022/14/solver.lisp b/AoC2022/14/solver.lisp
index 188824b..0a2af57 100644
--- a/AoC2022/14/solver.lisp
+++ b/AoC2022/14/solver.lisp
@@ -41,15 +41,19 @@
(< -1 y (grid-y-len grid)))
(+ x (* y (grid-x-len grid))))))
+(defun paired-range (fx tx fy ty grid)
+ (destructuring-bind ((fx tx) (fy ty)) (list (sort (list fx tx) #'<) (sort (list fy ty) #'<))
+ (loop for l from (solver-point fx fy grid) to (solver-point tx ty grid) by (if (= fx tx) (grid-x-len grid) 1)
+ collect l)))
+
+
+(defun place-wall (positions grid)
+ (loop for l in positions :do (setf (aref (grid-grid grid) l) 1)))
+
(defun solver--wall-line (grid walls)
(loop for line in walls
- do (loop for ((startx starty) (fx fy)) on line until (null fx)
- :if (= startx fx)
- :do (loop for y from (min starty fy) to (max starty fy)
- :do (setf (aref (grid-grid grid) (solver-point startx y grid)) 1))
- :else
- :do (loop for x from (min startx fx) to (max startx fx)
- :do (setf (aref (grid-grid grid) (solver-point x starty grid)) 1)))))
+ do (loop for ((fx fy) (tx ty)) on line until (null tx)
+ :do (place-wall (paired-range fx tx fy ty grid) grid))))
(defun draw-grid (grid)
(let ((out (make-string-output-stream)))
@@ -65,22 +69,26 @@
(defun simulate (grid)
(let ((drops 0)
(x 500) (y 0))
- (loop while
- (ignore-errors ;; went out of grid
- (cond
- ((= 0 (aref (grid-grid grid) (solver-point x (1+ y) grid)))
- (incf y)) ;; check next
- ((= 0 (aref (grid-grid grid) (solver-point (1- x) (1+ y) grid)))
- (incf y)
- (decf x)) ;; check left
- ((= 0 (aref (grid-grid grid) (solver-point (1+ x) (1+ y) grid)))
- (incf y)
- (incf x)) ;; check right
- (t (setf (aref (grid-grid grid) (solver-point x y grid)) 2)
- (incf drops)
- (unless (= y 0)
- (setf x 500 y 0))))))
- drops))
+ (flet ((check (dir)
+ (when (= 0 (aref (grid-grid grid)
+ (ecase dir
+ (forward (solver-point x (1+ y) grid))
+ (left (solver-point (1- x) (1+ y) grid))
+ (right (solver-point (1+ x) (1+ y) grid)))))
+ (incf y))))
+ (handler-case
+ (loop while
+ (cond
+ ((check 'forward))
+ ((check 'left) (decf x))
+ ((check 'right) (incf x))
+ (t (setf (aref (grid-grid grid) (solver-point x y grid)) 2)
+ (incf drops)
+ (unless (= y 0)
+ (setf x 500 y 0)))))
+ (sb-int:invalid-array-index-error ()))
+
+ drops)))
(defun parse-location (list-str)
(mapcar (lambda (row)
@@ -94,11 +102,12 @@
(grid (funcall grid-constructor (bounds walls))))
(solver--wall-line grid walls)
(when (eq grid-constructor #'make-finite-grid)
- (loop with yrow = (* (grid-x-len grid) (1- (grid-y-len grid)))
- for x from 0 below (grid-x-len grid)
- do (setf (aref (grid-grid grid) (+ x yrow)) 1)))
+ (let ((b (grid-bounds grid)))
+ (place-wall
+ (paired-range (1- (elt b 1)) (elt b 2)
+ (1- (grid-y-len grid)) (1- (grid-y-len grid)) grid) grid)))
(values (simulate grid)
- (draw-grid grid))))
+ (draw-grid grid))))
(fiveam:test test
(let ((eg-data (uiop:split-string "498,4 -> 498,6 -> 496,6