Lisp
Part 1
(defun p1-process-line (line)
(mapcar #'parse-integer (str:words line)))
(defun line-direction-p (line)
"make sure the line always goes in the same direction"
(loop for x in line
for y in (cdr line)
count (> x y) into dec
count (< x y) into inc
when (and (> dec 0 ) (> inc 0)) return nil
when (= x y) return nil
finally (return t)))
(defun line-in-range-p (line)
"makes sure the delta is within 3"
(loop for x in line
for y in (cdr line)
for delta = (abs (- x y))
when (or (> delta 3) )
return nil
finally (return t)))
(defun test-line-p (line)
(and (line-in-range-p line) (line-direction-p line)))
(defun run-p1 (file)
(let ((data (read-file file #'p1-process-line)))
(apply #'+ (mapcar (lambda (line) (if (test-line-p line) 1 0)) data))))
Part 2
(defun test-line-p2 (line)
(or (test-line-p (cdr line))
(test-line-p (cdr (reverse line)))
(loop for back on line
collect (car back) into front
when (test-line-p (concatenate 'list front (cddr back)))
return t
finally (return nil)
)))
(defun run-p2 (file)
(let ((data (read-file file #'p1-process-line)))
(loop for line in data
count (test-line-p2 line))))
Lisp
Brute forced part 2, but got a lot of reuse from part 1.
Part 1 and 2