Skip to content

Commit

Permalink
Refactor 2023/24
Browse files Browse the repository at this point in the history
- Use DEFINE-SOLUTION, DEFINE-TEST
- Extract some functions to better explain what's going on -- for part
  2 in particular
  • Loading branch information
iamFIREcracker committed Feb 1, 2024
1 parent d819acf commit 64338f7
Showing 1 changed file with 47 additions and 30 deletions.
77 changes: 47 additions & 30 deletions src/2023/day24.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@


(defun hailstone (s) (extract-integers s))
#+#:excluded (hailstone "248315803897794, 386127890875011, 326651351825022 @ -89, -119, 32")

(defun parse-input (&optional (strings (uiop:read-file-lines #P"src/2023/day24.txt")))
(defun parse-input (&optional (strings (aoc::read-problem-input 2023 24)))
(mapcar #'hailstone strings))


Expand All @@ -21,13 +20,19 @@
(list (/ xnum den) (/ ynum den)))))


(defun ignore-axis (n h)
(destructuring-bind (x y z vx vy vz) h
(ecase n
(0 (list y z vy vz))
(1 (list x z vx vz))
(2 (list x y vx vy)))))

(defun in-the-future? (x1 y1 x2 y2 x3 y3)
(bnd* ((dx21 (- x2 x1)) (dx31 (- x3 x1))
(dy21 (- y2 y1)) (dy31 (- y3 y1)))
(and (>= (* dx21 dx31) 0)
(>= (* dy21 dy31) 0))))


(defun all-intersections (&optional (hh (parse-input)))
(looping
(dosublists (((x1 y1 vx1 vy1) . rest) hh)
Expand All @@ -40,42 +45,54 @@
(in-the-future? x3 y3 x4 y4 x y))
(collect! (list x y)))))))))))

(defun ignore-axis (n h)
(destructuring-bind (x y z vx vy vz) h
(ecase n
(0 (list y z vy vz))
(1 (list x z vx vz))
(2 (list x y vx vy)))))

#+#:excluded (length (all-intersections))
(defun part1 (&optional (hh (parse-input)))
(looping
(doseq ((x y) (all-intersections (mapcar [ignore-axis 2 _] hh)))
(count! (and (<= 200000000000000 x 400000000000000)
(<= 200000000000000 y 400000000000000))))))
#+#:excluded (part1 7 27)
#+#:excluded (part1 )
; 24999 nope
; 16779 !!!


;; We know a position <x, y, z> exists such that, if we throw a hail rock with
;; velocity <vx, vy, vz>, eventually it will collide with all the other rocks.
;; This means that if we subtract <vx, vy, vz> from each rock in our input,
;; eventually the rocks will all collide in <x, y, z>.
;;
;; So the idea is to take a few rocks from our input, brute-force a bunch of
;; velocities along each axis, adjust rocks velocities, and see where the rocks
;; collide.
;;
;; Re-using the logic from part1, we can find first where the rocks collide
;; along x and y first, and then along x and z.
;;
;; Kudos to: https://www.youtube.com/watch?v=nP2ahZs40U8
(defun adjust-velocity (dvx dvy h)
(destructuring-bind (x y vx vy) h
(list x y (+ vx dvx) (+ vy dvy))))
#+#:excluded (untrace adjust-velocity)

(defun find-single-intersection (hh)
(dorangei (vx -250 250)
(dorangei (vy -250 250)
(bnd1 (points (all-intersections (mapcar [adjust-velocity vx vy _]
hh)))
(when (and (> (length points) 1)
(= (length (remove-duplicates points :test #'equal)) 1))
(return-from find-single-intersection (first points)))))))

(defun part2 (&optional (hh (parse-input)))
(flet ((magic (axis &aux )
(bnd1 (hh (mapcar [ignore-axis axis _] (subseq hh 0 3)))
(dorangei (vx -300 300)
(dorangei (vy -300 300)
(bnd1 (points (all-intersections (mapcar [adjust-velocity vx vy _]
hh)))
(when (and (> (length points) 1)
(= (length (remove-duplicates points :test #'equal)) 1))
(return-from magic (first points)))))))))
(destructuring-bind (px1 py) (magic 2)
(destructuring-bind (px2 pz) (magic 1)
(assert (= px1 px2))
(+ px1 py pz)))))
#+#:excluded (time (part2))
; 871983857253169
(recursively ((hh (copy-seq hh)))
(setf hh (shuffle hh))
(bnd1 (sample (subseq hh 0 3))
(awhen (find-single-intersection (mapcar [ignore-axis 2 _] sample))
(destructuring-bind (px1 py) it
(awhen (find-single-intersection (mapcar [ignore-axis 1 _] sample))
(destructuring-bind (px2 pz) it
(assert (= px1 px2))
(return-from recur (+ px1 py pz)))))))
(recur hh)))


(define-solution (2023 24) (hh parse-input)
(values (part1 hh) (part2 hh)))

(define-test (2023 24) (16779 871983857253169))

0 comments on commit 64338f7

Please sign in to comment.