adventofcode2022

My solutions for Advent of Code 2022
Log | Files | Refs

commit d44443aadb80359e6113267856399cc001301e9b
parent 7d6cf65c3785908168567a2da695ac3d8e14fc1a
Author: Lukas Henkel <lh@entf.net>
Date:   Sun, 11 Dec 2022 14:02:12 +0100

Day 11 task 1

Diffstat:
Ainput/day11.txt | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/day11.lisp | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
At/day11.lisp | 35+++++++++++++++++++++++++++++++++++
3 files changed, 166 insertions(+), 0 deletions(-)

diff --git a/input/day11.txt b/input/day11.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 97, 81, 57, 57, 91, 61 + Operation: new = old * 7 + Test: divisible by 11 + If true: throw to monkey 5 + If false: throw to monkey 6 + +Monkey 1: + Starting items: 88, 62, 68, 90 + Operation: new = old * 17 + Test: divisible by 19 + If true: throw to monkey 4 + If false: throw to monkey 2 + +Monkey 2: + Starting items: 74, 87 + Operation: new = old + 2 + Test: divisible by 5 + If true: throw to monkey 7 + If false: throw to monkey 4 + +Monkey 3: + Starting items: 53, 81, 60, 87, 90, 99, 75 + Operation: new = old + 1 + Test: divisible by 2 + If true: throw to monkey 2 + If false: throw to monkey 1 + +Monkey 4: + Starting items: 57 + Operation: new = old + 6 + Test: divisible by 13 + If true: throw to monkey 7 + If false: throw to monkey 0 + +Monkey 5: + Starting items: 54, 84, 91, 55, 59, 72, 75, 70 + Operation: new = old * old + Test: divisible by 7 + If true: throw to monkey 6 + If false: throw to monkey 3 + +Monkey 6: + Starting items: 95, 79, 79, 68, 78 + Operation: new = old + 3 + Test: divisible by 3 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 7: + Starting items: 61, 97, 67 + Operation: new = old + 4 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 5 diff --git a/src/day11.lisp b/src/day11.lisp @@ -0,0 +1,76 @@ +(defpackage #:adventofcode2022/day11 + (:use #:cl #:adventofcode2022)) +(in-package #:adventofcode2022/day11) + +(defclass monkey () + ((items :initform nil + :accessor items) + (operation-fun :accessor operation-fun) + (test-fun :accessor test-fun) + (inspection-count :initform 0 + :accessor inspection-count))) + +(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 + ((str:starts-with-p "Monkey " input) + (setf current-monkey (make-instance 'monkey)) + (push current-monkey monkeys)) + ((str:starts-with-p " Starting items:" input) + (setf (items current-monkey) + (mapcar (lambda (x) (parse-integer x)) + (str:split ", " (subseq input 18))))) + ((str:starts-with-p " Operation:" input) + (setf (operation-fun current-monkey) + (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))) + ((str:starts-with-p " If true: throw to monkey" input) + (setf test-if-true (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))))))) + 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 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))))) + +(define-day 11 + () + #'task1 + nil) diff --git a/t/day11.lisp b/t/day11.lisp @@ -0,0 +1,35 @@ +(in-package #:adventofcode2022/test) + +(defconstant +testdata-day11+ "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") + +(def-test day11-task1 () + (is-true + (= 10605 + (run-task 11 1 + (make-string-input-stream +testdata-day11+)))))