(in-package :ca.mhcat.advent2022) ;; --- Day 4: Camp Cleanup --- ;; Space needs to be cleared before the last supplies can be ;; unloaded from the ships, and so several Elves have been ;; assigned the job of cleaning up sections of the camp. ;; Every section has a unique ID number, and each Elf is ;; assigned a range of section IDs. ;; However, as some of the Elves compare their section ;; assignments with each other, they've noticed that many of ;; the assignments overlap. To try to quickly find overlaps ;; and reduce duplicated effort, the Elves pair up and make ;; a big list of the section assignments for each pair (your ;; puzzle input). ;; For example, consider the following list of section ;; assignment pairs: ;; 2-4,6-8 ;; 2-3,4-5 ;; 5-7,7-9 ;; 2-8,3-7 ;; 6-6,4-6 ;; 2-6,4-8 ;; For the first few pairs, this list means: ;; Within the first pair of Elves, the first Elf was ;; assigned sections 2-4 (sections 2, 3, and 4), while ;; the second Elf was assigned sections 6-8 (sections 6, ;; 7, 8). ;; The Elves in the second pair were each assigned two ;; sections. ;; The Elves in the third pair were each assigned three ;; sections: one got sections 5, 6, and 7, while the ;; other also got 7, plus 8 and 9. ;; This example list uses single-digit section IDs to make ;; it easier to draw; your actual list might contain larger ;; numbers. Visually, these pairs of section assignments ;; look like this: ;; .234..... 2-4 ;; .....678. 6-8 ;; .23...... 2-3 ;; ...45.... 4-5 ;; ....567.. 5-7 ;; ......789 7-9 ;; .2345678. 2-8 ;; ..34567.. 3-7 ;; .....6... 6-6 ;; ...456... 4-6 ;; .23456... 2-6 ;; ...45678. 4-8 ;; Some of the pairs have noticed that one of their ;; assignments fully contains the other. For example, 2-8 ;; fully contains 3-7, and 6-6 is fully contained by 4-6. In ;; pairs where one assignment fully contains the other, one ;; Elf in the pair would be exclusively cleaning sections ;; their partner will already be cleaning, so these seem ;; like the most in need of reconsideration. In this ;; example, there are 2 such pairs. ;; In how many assignment pairs does one range fully contain ;; the other? (defparameter day4/test-data '("2-4,6-8" "2-3,4-5" "5-7,7-9" "2-8,3-7" "6-6,4-6" "2-6,4-8")) (defclass day4/range () ((start :initarg :start :initform 0 :reader start) (end :initarg :end :initform (error "can't guess the ending") :reader end))) (defmethod initialize-instance :after ((r day4/range) &key) (with-slots (start end) r (when (> start end) (error "can't have a range with a start after the end")))) (defgeneric day4/contains (r1 r2)) (defmethod day4/contains ((r1 day4/range) (r2 day4/range)) (with-slots (start end) r1 (and (<= start (start r2)) (>= end (end r2))))) (defun day4/total-overlap (range1 range2) (or (day4/contains range1 range2) (day4/contains range2 range1))) (defun day4/split-at (s ch) (let ((split-point (position ch s))) (list (subseq s 0 split-point) (subseq s (1+ split-point))))) (defun day4/parse-line (line) (flet ((make-range (pair) (make-instance 'day4/range :start (parse-integer (first pair)) :end (parse-integer (second pair))))) (let ((range-pairs (mapcar (lambda (s) (day4/split-at s #\-)) (day4/split-at line #\,)))) (mapcar #'make-range range-pairs)))) (defun day4/load-dataset (lst) (mapcar #'day4/parse-line lst)) (defun day4/compute (pred data) (let ((overlaps (mapcar (lambda (pair) (apply pred pair)) data))) (length (remove-if #'null overlaps)))) (defun day4/compute-part1 (data) (day4/compute #'day4/total-overlap data)) (defun day4/part1 () (day4/compute-part1 (day4/load-dataset (load-lines "day4.txt")))) ;; --- Part Two --- ;; It seems like there is still quite a bit of duplicate ;; work planned. Instead, the Elves would like to know the ;; number of pairs that overlap at all. ;; In the above example, the first two pairs (2-4,6-8 and ;; 2-3,4-5) don't overlap, while the remaining four pairs ;; (5-7,7-9, 2-8,3-7, 6-6,4-6, and 2-6,4-8) do overlap: ;; 5-7,7-9 overlaps in a single section, 7. ;; 2-8,3-7 overlaps all of the sections 3 through 7. ;; 6-6,4-6 overlaps in a single section, 6. ;; 2-6,4-8 overlaps in sections 4, 5, and 6. ;; So, in this example, the number of overlapping assignment ;; pairs is 4. ;; In how many assignment pairs do the ranges overlap? (defgeneric day4/overlaps (r1 r2)) (defmethod day4/overlaps ((r1 day4/range) (r2 day4/range)) (with-slots (start end) r1 (not (or (> start (end r2)) (< end (start r2)))))) (defun day4/compute-part2 (data) (day4/compute #'day4/overlaps data)) (defun day4/part2 () (day4/compute-part2 (day4/load-dataset (load-lines "day4.txt"))))