;; https://adventofcode.com/2022/day/15 (ql:quickload 'cl-ppcre) (defparameter *day15-input-file* "day15-test.txt") (defclass point () ((x :initarg :x :reader x) (y :initarg :y :reader y))) (defmethod print-object ((obj point) stream) (print-unreadable-object (obj stream :type t) (with-slots (x y) obj (format stream "x:~a y:~a" x y)))) (defmethod points-equal ((left point) (right point)) (and (= (x left) (x right)) (= (y left) (y right)))) (defclass sensor () ((self-coord :initarg :self :reader self-coord) (beacon-coord :initarg :beacon :reader beacon-coord) (covered-dist :initarg :dist :reader covered-dist))) (defun make-sensor (sens-x sens-y beac-x beac-y) (let* ((sensor (make-instance 'point :x sens-x :y sens-y)) (beacon (make-instance 'point :x beac-x :y beac-y)) (dist (manh-dist sensor beacon))) (make-instance 'sensor :self sensor :beacon beacon :dist dist))) (defmethod print-object ((obj sensor) stream) (print-unreadable-object (obj stream :type t) (with-slots (self-coord beacon-coord covered-dist) obj (format stream "at: ~a, linked to: ~a, covering dist: ~a" self-coord beacon-coord covered-dist)))) (defmethod can-have-unknown-beacon-p ((p point) (s sensor)) (> (manh-dist p (self-coord s)) (covered-dist s))) (defun line-to-coords (line) (rest (mapcar (lambda (str) (parse-integer str :junk-allowed t)) (cl-ppcre:split "=" line)))) (defun get-sensors-list (input-file-name) (mapcar (lambda (coords-list) (apply #'make-sensor coords-list)) (mapcar #'line-to-coords (uiop:read-file-lines input-file-name)))) (defun get-limits (sensors-list) (loop for sensor in sensors-list minimize (x (self-coord sensor)) into xs minimize (x (beacon-coord sensor)) into xs maximize (x (self-coord sensor)) into xm maximize (x (beacon-coord sensor)) into xm minimize (y (self-coord sensor)) into ys minimize (y (beacon-coord sensor)) into ys maximize (y (self-coord sensor)) into ym maximize (y (beacon-coord sensor)) into ym finally (return (list xs xm ys ym)))) (defun possible-to-have-beacon (point sensors) (let ((all-checks (mapcar (lambda (sensor) (if (points-equal point (beacon-coord sensor)) 'known-sensor (can-have-unknown-beacon-p point sensor) ; single NIL means - not possible to have unknown )) sensors))) (or (not (position nil all-checks)) ; nil if all sensors allow (said T) presense of unknown beacons (position 'known-sensor all-checks) ; exists known sensor ))) (defun count-certainly-not-beacons (input-file-name) (let ((sensors (get-sensors-list input-file-name))) (destructuring-bind (min-x max-x min-y max-y) (get-limits sensors) (let ((to-add-x (abs (- max-x min-x))) ;; (to-check-y 10) (to-check-y 2000000) ) (loop for x from (- min-x to-add-x) to (+ max-x to-add-x) count (not (possible-to-have-beacon (make-instance 'point :x x :y to-check-y) sensors)) do (format t "iterating for x:~a y:~a~%" x to-check-y)))))) (count-certainly-not-beacons "day15-test.txt") (count-certainly-not-beacons "day15-input.txt") ;; well, that's just too slow ;; how do i rewrite it to make it faster? ;; i guess i could exclude the sensors which are too far away from the list? ;; ;; well, optimization here that we move by 1 point toward or away from sensor ;; so, we can kind of calculate when we'll be in it's range? ;; * in what amount of steps ;; ** whoa, org colors ;; ;; so. ;; PART 2 - just start search overnight? ;; for 0 to 4.000.000 by x and y? ;; and collect all such possible x and y? ;; nope, even if it were 5 minutes for 16mil, ;; so 2 minutes per 4 mil, then multiply by 4M - more than a day. ;; think better