commit 8f99c2c14ba2ac0380e6fa5c7735de58553d5cab
parent d44443aadb80359e6113267856399cc001301e9b
Author: Lukas Henkel <lh@entf.net>
Date: Sun, 11 Dec 2022 14:44:00 +0100
Day 11 task 2
Diffstat:
3 files changed, 54 insertions(+), 35 deletions(-)
diff --git a/adventofcode2022.asd b/adventofcode2022.asd
@@ -16,7 +16,8 @@
(:file "day07")
(:file "day08")
(:file "day09")
- (:file "day10")))
+ (:file "day10")
+ (:file "day11")))
(defsystem "adventofcode2022/test"
:description "My solutions to the advent of code 2022"
@@ -36,4 +37,5 @@
(:file "day07")
(:file "day08")
(:file "day09")
- (:file "day10")))
+ (:file "day10")
+ (:file "day11")))
diff --git a/src/day11.lisp b/src/day11.lisp
@@ -6,6 +6,7 @@
((items :initform nil
:accessor items)
(operation-fun :accessor operation-fun)
+ (test-value :accessor test-value)
(test-fun :accessor test-fun)
(inspection-count :initform 0
:accessor inspection-count)))
@@ -13,7 +14,6 @@
(defun parse-monkeys (inputs)
(loop with monkeys = nil
with current-monkey = nil
- with test-divisible-by = nil
with test-if-true = nil
for input in inputs
do (cond
@@ -29,48 +29,59 @@
(eval (read-from-string
(format nil "(lambda (old) (~A old))" (subseq input 23))))))
((str:starts-with-p " Test: divisible by" input)
- (setf test-divisible-by (subseq input 21)))
+ (setf (test-value current-monkey) (parse-integer (subseq input 21))))
((str:starts-with-p " If true: throw to monkey" input)
- (setf test-if-true (subseq input 29)))
+ (setf test-if-true (parse-integer (subseq input 29))))
((str:starts-with-p " If false: throw to monkey" input)
(setf (test-fun current-monkey)
- (eval (read-from-string
- (format nil
- "(lambda (item) (if (= (mod item ~A) 0) ~A ~A))"
- test-divisible-by
- test-if-true
- (subseq input 29)))))))
+ (eval `(lambda (item)
+ (if (= (mod item ,(test-value current-monkey)) 0)
+ ,test-if-true
+ ,(parse-integer (subseq input 29))))))))
finally (return (coerce (reverse monkeys) 'vector))))
-(defun let-monkeys-play (monkeys rounds)
- (loop repeat rounds
- do (loop for monkey across monkeys
- do (loop with operation-fun = (operation-fun monkey)
- with test-fun = (test-fun monkey)
- for item in (items monkey)
- for new-item = (setf item
- (floor (/ (funcall operation-fun item) 3)))
- for next-monkey-index = (funcall test-fun new-item)
- for next-monkey = (aref monkeys next-monkey-index)
- do (incf (inspection-count monkey))
- do (setf (items next-monkey)
- (append (items next-monkey) (list new-item))))
- do (setf (items monkey) nil))))
+(defun let-monkeys-play (monkeys rounds &optional do-not-manage-worry-level?)
+ (loop
+ with test-value-product = (if do-not-manage-worry-level?
+ (apply #'* (map 'list #'test-value monkeys))
+ 0)
+ repeat rounds
+ do (loop for monkey across monkeys
+ do (loop with operation-fun = (operation-fun monkey)
+ with test-fun = (test-fun monkey)
+ for item in (items monkey)
+ for new-item = (let ((new-value (funcall operation-fun item)))
+ (if do-not-manage-worry-level?
+ (mod new-value test-value-product)
+ (floor (/ new-value 3))))
+ for next-monkey-index = (funcall test-fun new-item)
+ for next-monkey = (aref monkeys next-monkey-index)
+ do (incf (inspection-count monkey))
+ do (setf (items next-monkey)
+ (append (items next-monkey) (list new-item))))
+ do (setf (items monkey) nil))))
+
+(defun get-monkey-business (monkeys)
+ (apply #'*
+ (map 'list
+ #'inspection-count
+ (subseq (sort monkeys
+ (lambda (monkey-1 monkey-2)
+ (> (inspection-count monkey-1)
+ (inspection-count monkey-2))))
+ 0 2))))
(defun task1 (inputs)
(let ((monkeys (parse-monkeys inputs)))
(let-monkeys-play monkeys 20)
- (apply #'*
- (map 'list
- (lambda (monkey)
- (inspection-count monkey))
- (subseq (sort monkeys
- (lambda (monkey-1 monkey-2)
- (> (inspection-count monkey-1)
- (inspection-count monkey-2))))
- 0 2)))))
+ (get-monkey-business monkeys)))
+
+(defun task2 (inputs)
+ (let ((monkeys (parse-monkeys inputs)))
+ (let-monkeys-play monkeys 10000 t)
+ (get-monkey-business monkeys)))
(define-day 11
()
#'task1
- nil)
+ #'task2)
diff --git a/t/day11.lisp b/t/day11.lisp
@@ -33,3 +33,9 @@ Monkey 3:
(= 10605
(run-task 11 1
(make-string-input-stream +testdata-day11+)))))
+
+(def-test day11-task2 ()
+ (is-true
+ (= 2713310158
+ (run-task 11 2
+ (make-string-input-stream +testdata-day11+)))))