diff options
-rw-r--r-- | AoC2023/day09/solver.lisp | 62 |
1 files changed, 30 insertions, 32 deletions
diff --git a/AoC2023/day09/solver.lisp b/AoC2023/day09/solver.lisp index d515317..3df0cc3 100644 --- a/AoC2023/day09/solver.lisp +++ b/AoC2023/day09/solver.lisp @@ -1,46 +1,44 @@ ;;03:39 +;;04:07 Solved +;;05:24 Painful refactorins (ql:quickload '(fiveam arrows transducers)) + (defparameter eg-input "0 3 6 9 12 15 1 3 6 10 15 21 10 13 16 21 30 45") (defun row-reducer (row) - (loop for (a b) on row by #'cdr - until (null b) - collect (- b a))) + (mapcar #'- (cdr row) row)) (defun terminal-p (row) - (every #'zerop row)) + (every #'= (cdr row) row)) -(defun forward (row) +(defun get-coefs (row pick &optional acc) (if (terminal-p row) - 0 - (+ (forward (row-reducer row)) (car (last row))))) + (nreverse (cons (funcall pick row) acc)) + (get-coefs (row-reducer row) pick (cons (funcall pick row) acc)))) -(defun backward (row) - (if (terminal-p row) - 0 - (- (car row) (backward (row-reducer row))))) - -(defun solver1 (lines) - (arrows:->> - lines - (mapcar (lambda (line) - (forward - (mapcar #'parse-integer (uiop:split-string line))))) - (apply #'+))) - -(defun solver2 (lines) - (arrows:->> - lines - (mapcar (lambda (line) - (backward - (mapcar #'parse-integer (uiop:split-string line))))) - (apply #'+))) +(defun parse-line (line) + (mapcar #'parse-integer (uiop:split-string line))) -(fiveam:test solutions - (fiveam:is (= 114 (solver1 (uiop:split-string eg-input :separator '(#\Newline))))) - (fiveam:is (= 2105961943 (solver1 (uiop:read-file-lines "input")))) +(defun forward (line) + (reduce #'+ (get-coefs line (lambda (a) (car (last a)))))) - (fiveam:is (= 2 (solver2 (uiop:split-string eg-input :separator '(#\Newline))))) - (fiveam:is (= 1019 (solver2 (uiop:read-file-lines "input"))))) +(defun backward (line) + (reduce #'- (get-coefs line #'car) :from-end t)) + +(defun solver (lines key) + (reduce #'+ + (mapcar #'parse-line lines) + :key key)) + +(fiveam:test solutions + (fiveam:is (= 114 (solver (uiop:split-string eg-input :separator '(#\Newline)) + #'forward))) + (fiveam:is (= 2105961943 (solver (uiop:read-file-lines "input") + #'forward))) + + (fiveam:is (= 2 (solver (uiop:split-string eg-input :separator '(#\Newline)) + #'backward))) + (fiveam:is (= 1019 (solver (uiop:read-file-lines "input") + #'backward)))) |