advent-of-code-2024

My solutions to AoC 2024
Log | Files | Refs

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))))