aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2023/day09/solver.lisp
blob: 3df0cc3f71c1a42f277fbcfb6c34b8b7077ed0ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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)
  (mapcar #'- (cdr row) row))

(defun terminal-p (row)
  (every #'= (cdr row) row))

(defun get-coefs (row pick &optional acc)
  (if (terminal-p row)
      (nreverse (cons (funcall pick row) acc))
      (get-coefs (row-reducer row) pick (cons (funcall pick row) acc))))

(defun parse-line (line)
  (mapcar #'parse-integer (uiop:split-string line)))

(defun forward (line)
  (reduce #'+ (get-coefs line (lambda (a) (car (last a))))))

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