diff options
| author | Syndamia <kamen@syndamia.com> | 2022-12-11 20:28:35 +0200 |
|---|---|---|
| committer | Syndamia <kamen@syndamia.com> | 2022-12-11 20:28:35 +0200 |
| commit | 8eb6f9a713c7b7175eedf8d833493036a4c7d333 (patch) | |
| tree | 12cb8a0908d14ecc6e1a1eded2c7c791e107d960 /2022/Day11 | |
| parent | 7fdd719af085daa6a35f004c0b8013b38ebf9178 (diff) | |
| download | advent-of-code-8eb6f9a713c7b7175eedf8d833493036a4c7d333.tar advent-of-code-8eb6f9a713c7b7175eedf8d833493036a4c7d333.tar.gz advent-of-code-8eb6f9a713c7b7175eedf8d833493036a4c7d333.zip | |
[2022/D11] Solved second part and reworked a bit first part of today's task
Diffstat (limited to '2022/Day11')
| -rw-r--r-- | 2022/Day11/part-one.cl | 23 | ||||
| -rw-r--r-- | 2022/Day11/part-two.cl | 109 |
2 files changed, 119 insertions, 13 deletions
diff --git a/2022/Day11/part-one.cl b/2022/Day11/part-one.cl index 29f5b93..afab3ed 100644 --- a/2022/Day11/part-one.cl +++ b/2022/Day11/part-one.cl @@ -35,22 +35,19 @@ (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)) - + (flet ((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)))))) + (create-test-function (inpt) + (eval `(lambda (worry-level) + (zerop (% worry-level ,(parse-integer inpt :start 21))))))) ; In the input we only test for divisibility (doread-lines (inpt :read-line-options (prog-input NIL)) (cond ((zerop (length inpt))) ; Do nothing on empty lines @@ -98,4 +95,4 @@ if (< (monkey-inspections m) biggest) maximize (monkey-inspections m) into second-biggest finally - (print (* biggest second-biggest)))))) + (print (* biggest second-biggest))))))) diff --git a/2022/Day11/part-two.cl b/2022/Day11/part-two.cl new file mode 100644 index 0000000..362be8b --- /dev/null +++ b/2022/Day11/part-two.cl @@ -0,0 +1,109 @@ +;;; https://gitlab.com/Syndamia/senzill +(require :senzill) +(use-package :senzill.math) +(use-package :senzill.collections) +(use-package :senzill.io) + +(defparameter +rounds+ 10000) + +(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) (modder integer)) + (setf (first (monkey-items m)) + (% (funcall (monkey-operation m) (first (monkey-items m))) modder)) + (++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)))) + + + +(ask-for-stream (prog-input) + (let ((monkeys '()) (modder 1) (buffer-items '()) (buffer-operation NIL) (buffer-test NIL) (buffer-throw-t -1) (buffer-throw-f -1)) + (flet ((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)))))) + (create-test-function (inpt) + (eval `(lambda (worry-level) + (zerop (% worry-level ,(parse-integer inpt :start 21))))))) ; In the input we only test for divisibility + + + (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: + ;; If we had one monkey, we could just mod the worry level, this way we + ;; reduce the number by not changing the outcome of the Test + ;; For two or more monkeys, we want this property to hold, so we need + ;; our number to be divisible by all the Test values, hence we mod + ;; by a number, divisible by all of those values. + ;; The smallest such number is the multiplication of all of those values. + ;; I was 99.99% there on figuring it out, but I still needed to look. + ;; Thanks https://github.com/arcogelderblom/AdventOfCode2022/ + (*= modder (parse-integer inpt :start 21)) + (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) + modder)))) + + (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))))))) |
