Add solution for part 1 for day 11

This commit is contained in:
Tobias Eidelpes 2022-12-11 18:22:19 +01:00
parent cca98607c9
commit 8b1d2b2ce5
3 changed files with 175 additions and 0 deletions

93
day11/day11.lisp Normal file
View File

@ -0,0 +1,93 @@
(ql:quickload :cl-ppcre)
(defclass monkey ()
((items
:accessor items
:initarg :items
:type list)
(op
:accessor op
:initarg :op
:type function)
(test
:accessor test
:initarg :test
:type function)
(actions
:accessor actions
:initarg :actions
:type list)
(inspections
:accessor inspections
:initarg :inspections
:type number)))
(defparameter *regexp* "Monkey (\\d+):\\n Starting items: ([0-9, ]+)\\n Operation: new = old ([\*\+]) (\\d+|\\w+)\\n Test: divisible by (\\d+)\\n If true: throw to monkey (\\d+)\\n If false: throw to monkey (\\d+)")
(defun str-to-list (str)
"Parses comma-separated string of integers in STR into a list of
integers."
(loop :for item :in (ppcre:split ", " str) :collect (parse-integer item)))
(defun make-op (operation operand)
"Returns a function matching the description given by STR."
(if (equal operand "old")
(if (equal operation "*")
(lambda (old) (* old old))
(lambda (old) (+ old old)))
(if (equal operation "*")
(lambda (old) (* old (parse-integer operand)))
(lambda (old) (+ old (parse-integer operand))))))
(defun make-test (str)
"Returns a function testing for divisibility by the number given in
STR."
(lambda (level) (zerop (mod level (parse-integer str)))))
(defun throw-item (monkeys src dest)
"Removes the first item held by the monkey at position SRC in MONKEYS
and adds it to the end of the items held by the monkey at position
DEST in MONKEYS."
(progn
(setf (items (nth dest monkeys))
(append (items (nth dest monkeys)) (list (car (items (nth src monkeys))))))
(setf (items (nth src monkeys))
(cdr (items (nth src monkeys))))))
(defun parse-input (input)
"Parses INPUT into a list of monkey objects."
(loop :for monkey
:in (ppcre:split "\\n\\n" (uiop:read-file-string input))
:collect
(ppcre:do-register-groups (id items operation operand test true false) (*regexp* monkey)
(return (make-instance 'monkey
:items (str-to-list items)
:op (make-op operation operand)
:test (make-test test)
:actions (list (parse-integer id) (parse-integer true)
(parse-integer id) (parse-integer false))
:inspections 0)))))
(defun run-round (monkeys div)
(let ((level 0))
(loop :for monkey :in monkeys :do
(loop :for item :in (items monkey) :do
(progn
(setf (inspections monkey) (1+ (inspections monkey)))
(setq level (funcall (op monkey) item))
(setq level (floor level div))
(setf (items monkey) (cons level (cdr (items monkey))))
(if (funcall (test monkey) level)
(throw-item monkeys (first (actions monkey)) (second (actions monkey)))
(throw-item monkeys (third (actions monkey)) (fourth (actions monkey)))))))
monkeys))
(defun solution (input div rounds)
"Run ROUNDS number of rounds on INPUT and use divisor DIV."
(let ((monkeys (parse-input input)))
(loop :for round :upto (1- rounds) :do
(run-round monkeys div))
(reduce '* (subseq (sort (loop :for monkey :in monkeys :collect (inspections monkey)) '>) 0 2))))
(solution "./input" 3 20)
(solution "./input" 1 10000)

55
day11/input Normal file
View File

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 91, 58, 52, 69, 95, 54
Operation: new = old * 13
Test: divisible by 7
If true: throw to monkey 1
If false: throw to monkey 5
Monkey 1:
Starting items: 80, 80, 97, 84
Operation: new = old * old
Test: divisible by 3
If true: throw to monkey 3
If false: throw to monkey 5
Monkey 2:
Starting items: 86, 92, 71
Operation: new = old + 7
Test: divisible by 2
If true: throw to monkey 0
If false: throw to monkey 4
Monkey 3:
Starting items: 96, 90, 99, 76, 79, 85, 98, 61
Operation: new = old + 4
Test: divisible by 11
If true: throw to monkey 7
If false: throw to monkey 6
Monkey 4:
Starting items: 60, 83, 68, 64, 73
Operation: new = old * 19
Test: divisible by 17
If true: throw to monkey 1
If false: throw to monkey 0
Monkey 5:
Starting items: 96, 52, 52, 94, 76, 51, 57
Operation: new = old + 3
Test: divisible by 5
If true: throw to monkey 7
If false: throw to monkey 3
Monkey 6:
Starting items: 75
Operation: new = old + 5
Test: divisible by 13
If true: throw to monkey 4
If false: throw to monkey 2
Monkey 7:
Starting items: 83, 75
Operation: new = old + 1
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 6

27
day11/input-test Normal file
View File

@ -0,0 +1,27 @@
Monkey 0:
Starting items: 79, 98
Operation: new = old * 19
Test: divisible by 23
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 54, 65, 75, 74
Operation: new = old + 6
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 0
Monkey 2:
Starting items: 79, 60, 97
Operation: new = old * old
Test: divisible by 13
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 3:
Starting items: 74
Operation: new = old + 3
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 1