commit - be08f67cded6e0367aeb15c08edd637f31e98965
commit + 5ebe82fbf80d12d57735a7ddd314db7ecc3e132f
blob - 4169f872e275615cd5868bf159c7d1de0478d337
blob + 146ba36404a2684aecfd0cfba9c183c8880615f7
--- src/day-2.lisp
+++ src/day-2.lisp
(:export #:day-2))
(in-package #:aoc/day-2)
-(defun report-safe-p (report)
- (loop with dir = (if (> (first report) (second report)) #'> #'<)
- with last = (first report)
- for current in (cdr report)
- for diff = (abs (- last current))
- unless (funcall dir last current)
- do (return nil)
- unless (<= diff 3)
- do (return nil)
- do (setf last current)
+(defun report-safe-p (report &key direction allow-skip)
+ (when (null direction)
+ (return-from report-safe-p
+ (or (report-safe-p report :direction #'< :allow-skip allow-skip)
+ (report-safe-p report :direction #'> :allow-skip allow-skip))))
+ (when (null (cdr report))
+ (return-from report-safe-p t))
+ (loop with last = nil
+ for cdr on report
+ until (null (cdr cdr))
+ for left = (car cdr)
+ for right = (cadr cdr)
+ for diff = (abs (- left right))
+ for cdir = (funcall direction left right)
+ unless (and cdir (<= diff 3))
+ do (return (when allow-skip
+ (or (report-safe-p (cons left (cddr cdr)) :direction direction)
+ (if (null last)
+ (report-safe-p (cdr cdr) :direction direction)
+ (report-safe-p (cons (car last) (cdr cdr)) :direction direction)))))
+ do (setf last cdr)
finally (return t)))
-(defun remove-nth (n list)
- (concatenate 'list
- (subseq list 0 n)
- (subseq list (1+ n))))
-
-(defun report-somewhat-safe-p (report)
- (or (report-safe-p report)
- (loop for i from 0 below (length report)
- for nr = (remove-nth i report)
- when (report-safe-p nr)
- do (return t))))
-
(defun day-2 (input)
(loop for line = (read-line input nil)
until (null line)
for report = (read-number-list line)
when (report-safe-p report)
sum 1 into task-1
- when (report-somewhat-safe-p report)
+ when (report-safe-p report :allow-skip t)
sum 1 into task-2
finally (return (values task-1 task-2))))
blob - 24d79613f13689146fab0aecbfb92ffc84abf984
blob + 17bd3b5b674bdf909b561a6d8cd0b6806e626c2f
--- t/day-2.lisp
+++ t/day-2.lisp
(define-test test-day-2
()
+ ;;; Test resets
+ ;; Report where the first item needs to be skipped
+ (assert (aoc/day-2::report-safe-p (list 30 24 25 28 31 33 35) :allow-skip t))
+ ;; Report where the second item needs to be skipped
+ (assert (aoc/day-2::report-safe-p (list 24 21 25 28 31 33 35) :allow-skip t))
+ ;; Report where reset target needs to be removed
+ (assert (aoc/day-2::report-safe-p (list 25 22 19 21 20 17 14 13) :allow-skip t))
+ ;;; Test task 1 & 2
(multiple-value-bind (task-1 task-2)
(aoc:run-day 2 "7 6 4 2 1
1 2 7 8 9