-
Notifications
You must be signed in to change notification settings - Fork 0
/
day11.lisp
62 lines (55 loc) · 2.32 KB
/
day11.lisp
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
56
57
58
59
60
61
62
(in-package :aoc-2022)
(defstruct monkey
id items operation test-num throw-to inspections)
(defun parse-monkey ()
(with-monad
(parse-string "Monkey ")
(assign id (parse-number))
(parse-until (parse-string "Starting items: "))
(assign items (parse-list (parse-number) ", "))
(parse-until (parse-string "Operation: new = "))
(assign operation (parse-list (either (parse-number) (parse-keyword)) " "))
(parse-until (parse-string "Test: divisible by "))
(assign test-num (parse-number))
(assign throw-to (n-of 2 (with-monad
(parse-until (parse-string "throw to monkey "))
(parse-number))))
(n-of 2 (parse-newline))
(unit (make-monkey :id id
:items items
:operation operation
:test-num test-num
:throw-to throw-to
:inspections 0))))
(defun parse-file ()
(one-or-more (parse-monkey)))
(defun apply-operation (old-val operation)
(let ((substituted (substitute old-val :old operation)))
(funcall (ecase (second substituted) (:+ #'+) (:* #'*))
(first substituted)
(third substituted))))
(defun monkey-turn (monkey monkeys modulus part)
(with-slots (items operation test-num throw-to inspections) monkey
(iter
(for item in items)
(incf inspections)
(for worry-level = (mod (floor (apply-operation item operation)
(if (= part 1) 3 1))
modulus))
(for target-id = (if (zerop (mod worry-level test-num))
(first throw-to)
(second throw-to)))
(with-slots ((target-items items)) (elt monkeys target-id)
(setf target-items (append target-items (list worry-level)))))
(setf items '())))
(defun monkey-business (monkeys)
(reduce #'* (subseq (sort (mapcar #'monkey-inspections monkeys) #'>) 0 2)))
(defun day11 (input &key (part 1))
(let* ((monkeys (run-parser (parse-file) input))
(modulus (reduce #'* (mapcar #'monkey-test-num monkeys))))
(iter
(repeat (if (= part 1) 20 10000))
(iter
(for monkey in monkeys)
(monkey-turn monkey monkeys modulus part))
(finally (return (monkey-business monkeys))))))