diff options
| author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-21 04:25:23 +0100 | 
|---|---|---|
| committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-21 04:25:23 +0100 | 
| commit | e5c805a17a2df715bd5c4ec4cda1bbb2aa5ad4db (patch) | |
| tree | 1da631930e372d24d460e546cd9ba889d2d2a6af /2022/puzzle-9.lisp | |
| parent | b99cda70877d5d2aeefb3cc3fdaa3b60a9755059 (diff) | |
| download | advent-of-code-e5c805a17a2df715bd5c4ec4cda1bbb2aa5ad4db.tar.gz advent-of-code-e5c805a17a2df715bd5c4ec4cda1bbb2aa5ad4db.tar.bz2 advent-of-code-e5c805a17a2df715bd5c4ec4cda1bbb2aa5ad4db.zip | |
Finished round 2 of puzzle 9
Annoying bug that took ages to fix: for multi-execute, there may be
times where movements go in complete diagonals.  In this case, we need
to move in the unit vector diagonal direction.  So I modified
update-tail for this case.  Never happens in round 1 lol.
Diffstat (limited to '2022/puzzle-9.lisp')
| -rw-r--r-- | 2022/puzzle-9.lisp | 140 | 
1 files changed, 78 insertions, 62 deletions
| diff --git a/2022/puzzle-9.lisp b/2022/puzzle-9.lisp index d27234b..e468627 100644 --- a/2022/puzzle-9.lisp +++ b/2022/puzzle-9.lisp @@ -1,7 +1,11 @@  (load "lib") +  (defparameter input (uiop:read-file-string "9-input"))  (defparameter lines (get-lines input)) +(defun coords-eq? (x y) +  (and (= (car x) (car y)) (= (cdr x) (cdr y)))) +  (defun move (P X Y)    (cons (+ (car P) X) (+ (cdr P) Y))) @@ -13,73 +17,85 @@  (defun update-tail (TAIL HEAD)    (let ((xd (- (car HEAD) (car TAIL)))          (yd (- (cdr HEAD) (cdr TAIL)))) -    (if (and (<= (abs xd) 1) (<= (abs yd) 1)) -        ;; Leave as is -        TAIL -        (cond -          ;; Diagonal movements -          ((and (= 1 (abs xd)) (= 2 (abs yd))) -           (move TAIL xd (-1unit yd))) -          ((and (= 1 (abs yd)) (= 2 (abs xd))) -           (move TAIL (-1unit xd) yd)) -          ;; Linear movements on an axis -          ((= (abs xd) 2) -           (move TAIL (-1unit xd) 0)) -          ((= (abs yd) 2) -           (move TAIL 0 (-1unit yd))))))) - -(defun move-direction (direction P) -  (case direction -    (R (move P 1 0)) -    (L (move P -1 0)) -    (U (move P 0 1)) -    (D (move P 0 -1)))) - -(defun print-grid (head tail) -  (destructuring-bind (hx . hy) head -    (destructuring-bind (tx . ty) tail -      (loop for x from 0 to 6 -            do -               (format t "-")) -      (format t "~%") -      (loop for y from 6 downto 0 -            do -               (progn -                 (format t "~d: " y) -                 (loop for x from 0 to 6 -                       do -                          (format t "~s" -                                  (cond -                                    ((and (= hx x) (= hy y)) 'H) -                                    ((and (= tx x) (= ty y)) 'T) -                                    (t '-)))) -                 (format t "~%")))))) +    (cond +      ;; Still touching +      ((and (<= (abs xd) 1) (<= (abs yd) 1)) TAIL) +      ;; These do the diagonal one steps +      ((and (= 1 (abs xd)) (= 2 (abs yd))) +       (move TAIL xd (-1unit yd))) +      ((and (= 1 (abs yd)) (= 2 (abs xd))) +       (move TAIL (-1unit xd) yd)) +      ;; Do the diagonal 2 steps (may happen on round 2) +      ((and (= 2 (abs xd)) (= 2 (abs yd))) +       (move TAIL (-1unit xd) (-1unit yd))) +      ;; Linear movements on an axis +      ((= (abs xd) 2) +       (move TAIL (-1unit xd) 0)) +      ((= (abs yd) 2) +       (move TAIL 0 (-1unit yd))))))  (defun parse-line (line)    (cons (intern (subseq line 0 1))          (parse-integer (subseq line 2)))) -(defun coords-eq? (x y) -  (and (= (car x) (car y)) (= (cdr x) (cdr y)))) +(defun move-direction (direction point) +  (case direction +    (R (move point 1 0)) +    (U (move point 0 1)) +    (L (move point -1 0)) +    (D (move point 0 -1)))) -(defun single-knot-execute-line (line head tail points) -  (destructuring-bind (direction . magnitude) (parse-line line) -    (dotimes (x magnitude) -      (setq head (move-direction direction head)) -      (setq tail (update-tail tail head)) -      (setq points (adjoin tail points :test #'coords-eq?)))) -  (values head tail points)) +(let nil +  (defun execute-line (line head tail points) +    (destructuring-bind (direction . magnitude) (parse-line line) +      (dotimes (x magnitude) +        (setq head (move-direction direction head)) +        (setq tail (update-tail tail head)) +        (setq points (adjoin tail points :test #'coords-eq?)))) +    (values head tail points)) -(defun single-knot-execute-lines (lines &optional head tail points) -  (if (null lines) -      (values -       head tail points) -      (let ((line (car lines)) -            (head (or head `(0 . 0))) -            (tail (or tail `(0 . 0))) -            (points (or points nil))) -        (multiple-value-bind (head tail points) (single-knot-execute-line line head tail points) -          (single-knot-execute-lines (cdr lines) head tail points))))) +  (defun execute-lines (lines &optional head tail points) +    (if (null lines) +        (values +         head tail points) +        (let ((line (car lines)) +              (head (or head `(0 . 0))) +              (tail (or tail `(0 . 0))) +              (points (or points nil))) +          (multiple-value-bind (head tail points) (execute-line line head tail points) +            (execute-lines (cdr lines) head tail points))))) -(format t "round 1: ~s~%" -        (length (car (last (multiple-value-list (single-knot-execute-lines lines)))))) +  (format t "round 1: ~s~%" +          (length (car (last (multiple-value-list (execute-lines lines))))))) + +(let nil +  (defun update-knots (head knots) +    (let ((new-knots (list (update-tail (car knots) head)))) +      (loop for knot in (cdr knots) +            do +               (setq new-knots (cons (update-tail knot (car new-knots)) new-knots))) +      new-knots)) + +  (defun execute-line (line head knots points) +    (destructuring-bind (direction . magnitude) (parse-line line) +      (dotimes (x magnitude) +        (setq head (move-direction direction head)) +        (setq knots (update-knots head knots)) +        (setq points (adjoin (car knots) points :test #'coords-eq?)) +        (setq knots (reverse knots)))) +    (values head knots points)) + +  (defun execute-lines (lines) +    (let ((head `(0 . 0)) +          (knots (loop for x from 1 to 9 collect `(0 . 0))) +          (points nil)) +      (loop for line in lines +            do +               (multiple-value-bind (nhead nknots npoints) +                   (execute-line line head knots points) +                 (setq head nhead +                       knots nknots +                       points npoints))) +      (values +       head knots points))) +  (format t "Round 2: ~a~%" (length (car (last (multiple-value-list (execute-lines lines))))))) | 
