(defpackage #:advent.2024.02 (:use #:cl)) (in-package #:advent.2024.02) (defvar *input* "02.input") ;;; Part 1 ;; How many lines contain monotonically increasing or decreasing numbers that ;; are all at least 1 and at most 3 apart? (defun parse (file) (loop for line in (uiop:read-file-lines file) collect (loop for num in (cl-ppcre:split "\\s+" line) collect (read-from-string num)))) (defun test-line (line) (and (or (apply #'> line) (apply #'< line)) (loop for (a b) on line when (and a b (> (abs (- a b)) 3)) do (return nil) finally (return t)))) (defun solve-1 () (count-if #'test-line (parse *input*))) ;;; Part 2 ;; How many lines meet 1's requirements when able to remove *one* element to ;; meet them? (defvar *unsafe* (remove-if #'test-line (parse *input*))) (defun generate-variations (list) "Generate all variations of LIST with one element removed." (loop for i from 0 to (1- (length list)) collect (remove-if (let ((j 0)) (lambda (x) (declare (ignorable x)) (prog1 (= i j) (incf j)))) list))) (defun solve-2 () (+ (solve-1) (count-if (lambda (line) (some #'test-line (generate-variations line))) *unsafe*)))