day-2.lisp (1436B)
1 (defpackage #:aoc/day-2 2 (:use #:cl #:aoc/utils) 3 (:export 4 #:report-safe-p 5 #:day-2)) 6 (in-package #:aoc/day-2) 7 8 (defun report-safe-p (report &key direction allow-skip) 9 (when (null direction) 10 (return-from report-safe-p 11 (or (report-safe-p report :direction #'< :allow-skip allow-skip) 12 (report-safe-p report :direction #'> :allow-skip allow-skip)))) 13 (when (null (cdr report)) 14 (return-from report-safe-p t)) 15 (loop with last = nil 16 for cdr on report 17 until (null (cdr cdr)) 18 for left = (car cdr) 19 for right = (cadr cdr) 20 for diff = (abs (- left right)) 21 for cdir = (funcall direction left right) 22 unless (and cdir (<= diff 3)) 23 do (return (when allow-skip 24 (or (report-safe-p (cons left (cddr cdr)) :direction direction) 25 (if (null last) 26 (report-safe-p (cdr cdr) :direction direction) 27 (report-safe-p (cons (car last) (cdr cdr)) :direction direction))))) 28 do (setf last cdr) 29 finally (return t))) 30 31 (defun day-2 (input) 32 (loop for line = (read-line input nil) 33 until (null line) 34 for report = (read-number-list line) 35 when (report-safe-p report) 36 sum 1 into task-1 37 when (report-safe-p report :allow-skip t) 38 sum 1 into task-2 39 finally (return (values task-1 task-2))))