Add solution for part 1 for day 11
This commit is contained in:
parent
cca98607c9
commit
8b1d2b2ce5
93
day11/day11.lisp
Normal file
93
day11/day11.lisp
Normal 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
55
day11/input
Normal 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
27
day11/input-test
Normal 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
|
||||
Loading…
x
Reference in New Issue
Block a user