diff options
Diffstat (limited to '2022')
| -rw-r--r-- | 2022/Day11/input-po.txt | 55 | ||||
| -rw-r--r-- | 2022/Day11/part-one.cl | 101 |
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)))))) |
