Monkey 0: Starting items: 57, 58 Operation: new = old * 19 Test: divisible by 7 If true: throw to monkey 2 If false: throw to monkey 3 Monkey 1: Starting items: 66, 52, 59, 79, 94, 73 Operation: new = old + 1 Test: divisible by 19 If true: throw to monkey 4 If false: throw to monkey 6 Monkey 2: Starting items: 80 Operation: new = old + 6 Test: divisible by 5 If true: throw to monkey 7 If false: throw to monkey 5 Monkey 3: Starting items: 82, 81, 68, 66, 71, 83, 75, 97 Operation: new = old + 5 Test: divisible by 11 If true: throw to monkey 5 If false: throw to monkey 2 Monkey 4: Starting items: 55, 52, 67, 70, 69, 94, 90 Operation: new = old * old Test: divisible by 17 If true: throw to monkey 0 If false: throw to monkey 3 Monkey 5: Starting items: 69, 85, 89, 91 Operation: new = old + 7 Test: divisible by 13 If true: throw to monkey 1 If false: throw to monkey 7 Monkey 6: Starting items: 75, 53, 73, 52, 75 Operation: new = old * 7 Test: divisible by 2 If true: throw to monkey 0 If false: throw to monkey 4 Monkey 7: Starting items: 94, 60, 79 Operation: new = old + 2 Test: divisible by 3 If true: throw to monkey 1 If false: throw to monkey 6 r'>summaryrefslogtreecommitdiffstats
path: root/AoC2023/day03/solver.lisp
blob: b326a88e941864b1940a262de16243005393dc77 (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
53
54
55
(ql:quickload '(fiveam cl-ppcre))

(defparameter eg-input "467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..")


(defun inbounds (row-max col-max)
  (lambda (cell)
    (destructuring-bind (row . col) cell
      (and (<= 0 row row-max)
           (<= 0 col col-max)))))

(defun in-line-numbers (line symbol-pos)
  (loop for (num-start num-end) on (cl-ppcre:all-matches "\\d+" line) by #'cddr
        when (<= (1- num-start) symbol-pos num-end)
          collect (parse-integer (subseq line num-start num-end))))

(defun adjacent-numbers (rows row limits symbol-pos)
  (loop for y in (list (1- row) row (1+ row))
        when (funcall limits (cons y symbol-pos))
          nconc (in-line-numbers (aref rows y) symbol-pos)))

(defun solver (lines symbol-regex reducer)
  (let* ((rows (make-array (length lines) :initial-contents lines
                                          :adjustable t))
         (limits (inbounds (1- (length lines))
                           (1- (length (car lines))))))
    (loop for row below (length lines)
          sum (loop for (start _end) on (cl-ppcre:all-matches symbol-regex (aref rows row)) by #'cddr
                    sum (funcall reducer (adjacent-numbers rows row limits start))))))

(defun solver1 (lines)
  (solver lines "[^.\\d]" (lambda (numbers) (apply #'+ numbers))))


(defun solver2 (lines)
  (solver lines "\\*"
          (lambda (ratios)
            (if (= 2 (length ratios))
                (* (car ratios) (cadr ratios))
                0))))

(fiveam:test solutions
  (fiveam:is (= 4361 (solver1 (uiop:split-string eg-input :separator '(#\Newline)))))
  (fiveam:is (= 467835  (solver2 (uiop:split-string eg-input :separator '(#\Newline)))))
  (fiveam:is (= 531561 (solver1 (uiop:read-file-lines "input"))))
  (fiveam:is (= 83279367(solver2 (uiop:read-file-lines "input")))))