aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2023/day15/solver.lisp
blob: 5bb25996e9383a51b59959cfd6433d636d8afe7f (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
45
46
47
48
49
50
51
52
;; 17:04
;; 17:34 part1
(ql:quickload '(fiveam str arrows))

(defparameter eg-in "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7")

(defun hash (str)
  (reduce
   (lambda (acc c)
     (mod (* 17 (+ acc (char-code c))) 256))
   str :initial-value 0))

(defun solve1 (in)
  (reduce #'+
          (str:split "," (str:trim in))
          :key #'hash))

(defun implement-instructions (instructions &aux (boxes (make-array 256 :initial-element nil)))
  (cl-ppcre:do-register-groups (label operator (#'parse-integer focal-length))
      ("(\\w+)([=-])(\\d+)?" instructions)
    (let ((content
            (aref boxes (hash label))))
      (flet ((is-lens (c) (equal (car c) label)))
        (arrows:->>
         (cond
           ((equal "-" operator)
            (remove-if #'is-lens content))
           ((equal "=" operator)
            (if (zerop (count-if #'is-lens content))
                (append content (list (cons label focal-length)))
                (mapcar
                 (lambda (c) (if (is-lens c)
                                 (cons label focal-length)
                                 c))
                 content))))
         (setf (aref boxes (hash label)))))))
  boxes)

(defun focusing-power (boxes)
  (loop for i from 1
        for lenses across boxes
        sum
        (* i (loop for j from 1
                   for (l . fl) in lenses
                   sum (* j fl)))))

(fiveam:test solutions
  (fiveam:is (= 52 (hash "HASH")))
  (fiveam:is (= 1320 (solve1 eg-in)))
  (fiveam:is (= 506437 (solve1 (uiop:read-file-string "input"))))
  (fiveam:is (= 145 (focusing-power (implement-instructions eg-in))))
  (fiveam:is (= 288521 (focusing-power (implement-instructions (uiop:read-file-string "input"))))))