80 lines
2.2 KiB
Common Lisp
80 lines
2.2 KiB
Common Lisp
(asdf:load-system "cl-strings")
|
|
(asdf:load-system "fiveam")
|
|
|
|
(require :cl-strings)
|
|
(require :fiveam)
|
|
|
|
(defvar *input*
|
|
(mapcar (lambda (line)
|
|
(mapcar (lambda (column) (parse-integer column))
|
|
(cl-strings:split line " ")))
|
|
(uiop:with-safe-io-syntax ()
|
|
(uiop:read-file-lines "input.txt"))))
|
|
|
|
(defun diff (record &optional results)
|
|
(if (null (cdr record))
|
|
(nreverse results)
|
|
(diff (cdr record) (cons (- (cadr record)
|
|
(car record))
|
|
results))))
|
|
|
|
(defun safep-1 (diff)
|
|
(or (every (lambda (n) (< 0 n 4)) diff)
|
|
(every (lambda (n) (< -4 n 0)) diff)))
|
|
|
|
(defun delete-nth (n list &optional result)
|
|
(cond
|
|
((null list) (nreverse result))
|
|
((= 0 n) (delete-nth (1- n) (cdr list) result))
|
|
(t (delete-nth (1- n) (cdr list) (cons (car list) result)))))
|
|
|
|
(defun permutations (list)
|
|
(labels ((permutations-1 (n results)
|
|
(if (> 0 n)
|
|
results
|
|
(permutations-1 (1- n) (cons (delete-nth n list) results)))))
|
|
(permutations-1 (1- (length list)) '())))
|
|
|
|
(defun safep (record)
|
|
(let ((diff (diff record)))
|
|
(or (safep-1 diff)
|
|
(some #'safep-1 (mapcar #'diff (permutations record))))))
|
|
|
|
(length (delete nil (mapcar #'safep *input*)))
|
|
|
|
(fiveam:def-suite example-suite :description "The example test suite.")
|
|
|
|
(fiveam:in-suite example-suite)
|
|
|
|
(fiveam:test empty-list
|
|
(fiveam:is (safep nil)))
|
|
|
|
(fiveam:test single-element
|
|
(fiveam:is (safep '(1))))
|
|
|
|
(fiveam:test multiple-elements
|
|
(fiveam:is (safep '(2 1))))
|
|
|
|
(fiveam:test big-diff-up-is-unsafe
|
|
(fiveam:is (not (safep '(1 2 7 8 9)))))
|
|
|
|
(fiveam:test big-diff-down-is-unsafe
|
|
(fiveam:is (not (safep '(9 7 6 2 1)))))
|
|
|
|
(fiveam:test a-single-error-is-permitted
|
|
(fiveam:is (safep '(1 3 2 4 5))))
|
|
|
|
(fiveam:test another-single-error-is-permitted
|
|
(fiveam:is (safep '(8 6 4 4 1))))
|
|
|
|
(fiveam:test safe-record-is-safe
|
|
(fiveam:is (safep '(1 3 6 7 9))))
|
|
|
|
(fiveam:test ignored-value-can-be-at-end
|
|
(fiveam:is (safep '(5 6 7 10 13 16 13))))
|
|
|
|
(fiveam:test more-than-one-error-is-not-permitted
|
|
(fiveam:is (not (safep '(17 18 18 19 16)))))
|
|
|
|
(fiveam:test what-goes-up-cannot-go-down
|
|
(fiveam:is (not (safep '(51 52 53 50 52)))))
|