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.
This commit is contained in:
@@ -1,7 +1,11 @@
|
|||||||
(load "lib")
|
(load "lib")
|
||||||
|
|
||||||
(defparameter input (uiop:read-file-string "9-input"))
|
(defparameter input (uiop:read-file-string "9-input"))
|
||||||
(defparameter lines (get-lines 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)
|
(defun move (P X Y)
|
||||||
(cons (+ (car P) X) (+ (cdr P) Y)))
|
(cons (+ (car P) X) (+ (cdr P) Y)))
|
||||||
|
|
||||||
@@ -13,73 +17,85 @@
|
|||||||
(defun update-tail (TAIL HEAD)
|
(defun update-tail (TAIL HEAD)
|
||||||
(let ((xd (- (car HEAD) (car TAIL)))
|
(let ((xd (- (car HEAD) (car TAIL)))
|
||||||
(yd (- (cdr HEAD) (cdr TAIL))))
|
(yd (- (cdr HEAD) (cdr TAIL))))
|
||||||
(if (and (<= (abs xd) 1) (<= (abs yd) 1))
|
(cond
|
||||||
;; Leave as is
|
;; Still touching
|
||||||
TAIL
|
((and (<= (abs xd) 1) (<= (abs yd) 1)) TAIL)
|
||||||
(cond
|
;; These do the diagonal one steps
|
||||||
;; Diagonal movements
|
((and (= 1 (abs xd)) (= 2 (abs yd)))
|
||||||
((and (= 1 (abs xd)) (= 2 (abs yd)))
|
(move TAIL xd (-1unit yd)))
|
||||||
(move TAIL xd (-1unit yd)))
|
((and (= 1 (abs yd)) (= 2 (abs xd)))
|
||||||
((and (= 1 (abs yd)) (= 2 (abs xd)))
|
(move TAIL (-1unit xd) yd))
|
||||||
(move TAIL (-1unit xd) yd))
|
;; Do the diagonal 2 steps (may happen on round 2)
|
||||||
;; Linear movements on an axis
|
((and (= 2 (abs xd)) (= 2 (abs yd)))
|
||||||
((= (abs xd) 2)
|
(move TAIL (-1unit xd) (-1unit yd)))
|
||||||
(move TAIL (-1unit xd) 0))
|
;; Linear movements on an axis
|
||||||
((= (abs yd) 2)
|
((= (abs xd) 2)
|
||||||
(move TAIL 0 (-1unit yd)))))))
|
(move TAIL (-1unit xd) 0))
|
||||||
|
((= (abs yd) 2)
|
||||||
(defun move-direction (direction P)
|
(move TAIL 0 (-1unit yd))))))
|
||||||
(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 "~%"))))))
|
|
||||||
|
|
||||||
(defun parse-line (line)
|
(defun parse-line (line)
|
||||||
(cons (intern (subseq line 0 1))
|
(cons (intern (subseq line 0 1))
|
||||||
(parse-integer (subseq line 2))))
|
(parse-integer (subseq line 2))))
|
||||||
|
|
||||||
(defun coords-eq? (x y)
|
(defun move-direction (direction point)
|
||||||
(and (= (car x) (car y)) (= (cdr x) (cdr y))))
|
(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)
|
(let nil
|
||||||
(destructuring-bind (direction . magnitude) (parse-line line)
|
(defun execute-line (line head tail points)
|
||||||
(dotimes (x magnitude)
|
(destructuring-bind (direction . magnitude) (parse-line line)
|
||||||
(setq head (move-direction direction head))
|
(dotimes (x magnitude)
|
||||||
(setq tail (update-tail tail head))
|
(setq head (move-direction direction head))
|
||||||
(setq points (adjoin tail points :test #'coords-eq?))))
|
(setq tail (update-tail tail head))
|
||||||
(values head tail points))
|
(setq points (adjoin tail points :test #'coords-eq?))))
|
||||||
|
(values head tail points))
|
||||||
|
|
||||||
(defun single-knot-execute-lines (lines &optional head tail points)
|
(defun execute-lines (lines &optional head tail points)
|
||||||
(if (null lines)
|
(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 (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
|
(values
|
||||||
head tail points)
|
head knots points)))
|
||||||
(let ((line (car lines))
|
(format t "Round 2: ~a~%" (length (car (last (multiple-value-list (execute-lines 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)))))
|
|
||||||
|
|
||||||
(format t "round 1: ~s~%"
|
|
||||||
(length (car (last (multiple-value-list (single-knot-execute-lines lines))))))
|
|
||||||
|
|||||||
Reference in New Issue
Block a user