aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2022/Day11/input-po.txt55
-rw-r--r--2022/Day11/part-one.cl101
2 files changed, 156 insertions, 0 deletions
diff --git a/2022/Day11/input-po.txt b/2022/Day11/input-po.txt
new file mode 100644
index 0000000..f505c2e
--- /dev/null
+++ b/2022/Day11/input-po.txt
@@ -0,0 +1,55 @@
+Monkey 0:
+ Starting items: 83, 97, 95, 67
+ Operation: new = old * 19
+ Test: divisible by 17
+ If true: throw to monkey 2
+ If false: throw to monkey 7
+
+Monkey 1:
+ Starting items: 71, 70, 79, 88, 56, 70
+ Operation: new = old + 2
+ Test: divisible by 19
+ If true: throw to monkey 7
+ If false: throw to monkey 0
+
+Monkey 2:
+ Starting items: 98, 51, 51, 63, 80, 85, 84, 95
+ Operation: new = old + 7
+ Test: divisible by 7
+ If true: throw to monkey 4
+ If false: throw to monkey 3
+
+Monkey 3:
+ Starting items: 77, 90, 82, 80, 79
+ Operation: new = old + 1
+ Test: divisible by 11
+ If true: throw to monkey 6
+ If false: throw to monkey 4
+
+Monkey 4:
+ Starting items: 68
+ Operation: new = old * 5
+ Test: divisible by 13
+ If true: throw to monkey 6
+ If false: throw to monkey 5
+
+Monkey 5:
+ Starting items: 60, 94
+ Operation: new = old + 5
+ Test: divisible by 3
+ If true: throw to monkey 1
+ If false: throw to monkey 0
+
+Monkey 6:
+ Starting items: 81, 51, 85
+ Operation: new = old * old
+ Test: divisible by 5
+ If true: throw to monkey 5
+ If false: throw to monkey 1
+
+Monkey 7:
+ Starting items: 98, 81, 63, 65, 84, 71, 84
+ Operation: new = old + 3
+ Test: divisible by 2
+ If true: throw to monkey 2
+ If false: throw to monkey 3
diff --git a/2022/Day11/part-one.cl b/2022/Day11/part-one.cl
new file mode 100644
index 0000000..29f5b93
--- /dev/null
+++ b/2022/Day11/part-one.cl
@@ -0,0 +1,101 @@
+;;; https://gitlab.com/Syndamia/senzill
+(require :senzill)
+(use-package :senzill.math)
+(use-package :senzill.collections)
+(use-package :senzill.io)
+
+(defparameter +rounds+ 20)
+
+(defclass monkey ()
+ ((items :initarg :items
+ :accessor monkey-items)
+ (inspections :initarg :inspections
+ :accessor monkey-inspections)
+ (operation :initarg :operation
+ :reader monkey-operation)
+ (test :initarg :test
+ :reader monkey-test)
+ (throw-true :initarg :throw-true
+ :reader monkey-throw-true)
+ (throw-false :initarg :throw-false
+ :reader monkey-throw-false))
+ (:default-initargs
+ :items '()
+ :inspections 0
+ :operation (lambda (old) old)
+ :test (lambda (worry-level) worry-level)
+ :throw-true 0
+ :throw-false 0))
+
+(defmethod inspect-and-throw ((m monkey) (monkey-true monkey) (monkey-false monkey))
+ (setf (first (monkey-items m))
+ (floor (/ (funcall (monkey-operation m) (first (monkey-items m))) 3)))
+ (++1 (monkey-inspections m))
+ (if (funcall (monkey-test m) (first (monkey-items m)))
+ (push-back (pop (monkey-items m)) (monkey-items monkey-true))
+ (push-back (pop (monkey-items m)) (monkey-items monkey-false))))
+
+(defun create-operation-function (inpt)
+ (eval `(lambda (old) (funcall ,(if (char= (char inpt 23) #\*) ; In the input, there is only * and +
+ #'*
+ #'+)
+ old
+ ,(if (char= (char inpt 25) #\o)
+ 'old
+ (parse-integer inpt :start 25))))))
+
+(defun create-test-function (inpt)
+ (eval `(lambda (worry-level)
+ (zerop (% worry-level ,(parse-integer inpt :start 21)))))) ; In the input we only test for divisibility
+
+(ask-for-stream (prog-input)
+ (let ((monkeys '()) (buffer-items '()) (buffer-operation NIL) (buffer-test NIL) (buffer-throw-t -1) (buffer-throw-f -1))
+
+
+ (doread-lines (inpt :read-line-options (prog-input NIL))
+ (cond ((zerop (length inpt))) ; Do nothing on empty lines
+ ((char= (char inpt 0) #\M) ; Monkey #:
+ (push-back (make-instance 'monkey :items buffer-items
+ :operation buffer-operation
+ :test buffer-test
+ :throw-true buffer-throw-t
+ :throw-false buffer-throw-f)
+ monkeys))
+ ((char= (char inpt 2) #\S) ; Starting items:
+ (setf buffer-items (loop for itms = (subseq inpt 18) then (subseq itms (+ 2 (position #\, itms)))
+ collect (parse-integer itms :junk-allowed T)
+ while (position #\, itms))))
+ ((char= (char inpt 2) #\O) ; Operation:
+ (setf buffer-operation (create-operation-function inpt)))
+ ((char= (char inpt 2) #\T) ; Test:
+ (setf buffer-test (create-test-function inpt)))
+ ((char= (char inpt 7) #\t) ; If true:
+ (setf buffer-throw-t (parse-integer inpt :start 29)))
+ ((char= (char inpt 7) #\f) ; If false:
+ (setf buffer-throw-f (parse-integer inpt :start 30)))))
+ ;; On very first line we add a monkey with default buffer values
+ (pop monkeys)
+ ;; The loop doesn't add the last monkey, since there is no new "Monkey #:" line
+ (push-back (make-instance 'monkey :items buffer-items
+ :operation buffer-operation
+ :test buffer-test
+ :throw-true buffer-throw-t
+ :throw-false buffer-throw-f)
+ monkeys)
+
+ (dotimes (r +rounds+)
+ (loop for m in monkeys
+ do (loop for item in (monkey-items m)
+ do (inspect-and-throw m
+ (nth (monkey-throw-true m) monkeys)
+ (nth (monkey-throw-false m) monkeys)))))
+
+ (loop for m in monkeys
+ maximize (monkey-inspections m) into biggest
+ finally
+ ;;; This loop is unnecessary, inefficient and stupid, but I'm extra lazy today
+ (loop for m in monkeys
+ if (< (monkey-inspections m) biggest)
+ maximize (monkey-inspections m) into second-biggest
+ finally
+ (print (* biggest second-biggest))))))