For day 14, we are given the initial positions and velocities of a number of robots that walk a 101x103 grid. These are parsed with a regular expression:
(in-package "ADVENT2024/DAY14") (defun read-input (input-file) (collect ’list (#M(lambda (line) (cl-ppcre:register-groups-bind ((#’parse-integer column) (#’parse-integer row) (#’parse-integer dx) (#’parse-integer dy)) ("p=(\\d+),(\\d+)\\s+v=(-?\\d+),(-?\\d+)" line) (list (coord column row) (coord dx dy)))) (scan-file input-file #’read-line))))
The robots walk a grid linearly. They do not interact with each other, and they wrap when they cross the edge of the grid.
(defun step-n (width height coord velocity n) (2v-mod (2v+ coord (2v* n velocity)) (coord width height)))
For part 1, we are asked to multiply the number of robots in each quadrant after 100 steps in a 101 x 103 grid.
(defun quadrant (width height coord) (let ((half-width (floor width 2)) (half-height (floor height 2))) (cond ((< (row coord) half-height) (cond ((< (column coord) half-width) 1) ((> (column coord) half-width) 2) (t nil))) ((> (row coord) half-height) (cond ((< (column coord) half-width) 3) ((> (column coord) half-width) 4) (t nil))) (t nil)))) (defparameter +grid-width+ 101) (defparameter +grid-height+ 103) (defun part-1 () (let ((quadrants (#M(lambda (coord) (quadrant +grid-width+ +grid-height+ coord)) (#M(lambda (robot) (step-n +grid-width+ +grid-height+ (first robot) (second robot) 100)) (scan 'list (read-input (input-pathname))))))) (* (collect-sum (#M(lambda (q) (if (eql q 1) 1 0)) quadrants)) (collect-sum (#M(lambda (q) (if (eql q 2) 1 0)) quadrants)) (collect-sum (#M(lambda (q) (if (eql q 3) 1 0)) quadrants)) (collect-sum (#M(lambda (q) (if (eql q 4) 1 0)) quadrants)))))
We’re told that the robots form a picture of a Christmas tree after a certain number of steps. This was a bit tricky to figure out, but I figured that if the robots were clumped together in a picture, the number of empty rows and columns elsewhere would be maximized. Robots return to their starting point every 101 x 103 steps, so we only need to check the first 10403 steps.
(defun occupied-row? (locs row) (find row locs :test #’= :key #’row)) (defun occupied-column? (locs column) (find column locs :test #’= :key #’column)) (defun score (locs) (+ (collect-length (choose-if #’not (#Moccupied-row? (series locs) (scan-range :from 0 :below +grid-height+)))) (collect-length (choose-if #’not (#Moccupied-column? (series locs) (scan-range :from 0 :below +grid-width+)))))) (defun part-2 () (let ((robots (read-input (input-pathname)))) (caar (sort (collect ’list (#M(lambda (n) (cons n (score (map ’list (lambda (robot) (step-n +grid-width+ +grid-height+ (first robot) (second robot) n)) robots)))) (scan-range :from 0 :below (* +grid-width+ +grid-height+)))) #’> :key #’cdr))))
No comments:
Post a Comment