Compare commits
No commits in common. "f612d15eedf553174f664b74916a4d9fa73d6022" and "65de39af730e5cd70e65bd0476fd41cc3000ea19" have entirely different histories.
f612d15eed
...
65de39af73
@ -1,55 +0,0 @@
|
|||||||
Monkey 0:
|
|
||||||
Starting items: 80
|
|
||||||
Operation: new = old * 5
|
|
||||||
Test: divisible by 2
|
|
||||||
If true: throw to monkey 4
|
|
||||||
If false: throw to monkey 3
|
|
||||||
|
|
||||||
Monkey 1:
|
|
||||||
Starting items: 75, 83, 74
|
|
||||||
Operation: new = old + 7
|
|
||||||
Test: divisible by 7
|
|
||||||
If true: throw to monkey 5
|
|
||||||
If false: throw to monkey 6
|
|
||||||
|
|
||||||
Monkey 2:
|
|
||||||
Starting items: 86, 67, 61, 96, 52, 63, 73
|
|
||||||
Operation: new = old + 5
|
|
||||||
Test: divisible by 3
|
|
||||||
If true: throw to monkey 7
|
|
||||||
If false: throw to monkey 0
|
|
||||||
|
|
||||||
Monkey 3:
|
|
||||||
Starting items: 85, 83, 55, 85, 57, 70, 85, 52
|
|
||||||
Operation: new = old + 8
|
|
||||||
Test: divisible by 17
|
|
||||||
If true: throw to monkey 1
|
|
||||||
If false: throw to monkey 5
|
|
||||||
|
|
||||||
Monkey 4:
|
|
||||||
Starting items: 67, 75, 91, 72, 89
|
|
||||||
Operation: new = old + 4
|
|
||||||
Test: divisible by 11
|
|
||||||
If true: throw to monkey 3
|
|
||||||
If false: throw to monkey 1
|
|
||||||
|
|
||||||
Monkey 5:
|
|
||||||
Starting items: 66, 64, 68, 92, 68, 77
|
|
||||||
Operation: new = old * 2
|
|
||||||
Test: divisible by 19
|
|
||||||
If true: throw to monkey 6
|
|
||||||
If false: throw to monkey 2
|
|
||||||
|
|
||||||
Monkey 6:
|
|
||||||
Starting items: 97, 94, 79, 88
|
|
||||||
Operation: new = old * old
|
|
||||||
Test: divisible by 5
|
|
||||||
If true: throw to monkey 2
|
|
||||||
If false: throw to monkey 7
|
|
||||||
|
|
||||||
Monkey 7:
|
|
||||||
Starting items: 77, 85
|
|
||||||
Operation: new = old + 6
|
|
||||||
Test: divisible by 13
|
|
||||||
If true: throw to monkey 4
|
|
||||||
If false: throw to monkey 0
|
|
@ -1,273 +0,0 @@
|
|||||||
|
|
||||||
;; monkeys https://adventofcode.com/2022/day/11
|
|
||||||
|
|
||||||
(defparameter *test-monkey-line* "Monkey 0:
|
|
||||||
Starting items: 79, 98, 101, 66
|
|
||||||
Operation: new = old * 19
|
|
||||||
Test: divisible by 23
|
|
||||||
If true: throw to monkey 2
|
|
||||||
If false: throw to monkey 3")
|
|
||||||
;;
|
|
||||||
;; so. i'd want to parse this string into list and it be a valid macro to return a monkey class
|
|
||||||
;; and have "turn" and "round" methods over the array of monkeys
|
|
||||||
|
|
||||||
(cl-ppcre:split " " (string-upcase *test-monkey-line*))
|
|
||||||
(cl-ppcre:split "\\n" (string-upcase *test-monkey-line*))
|
|
||||||
|
|
||||||
(defparameter num-plus-newline "9
|
|
||||||
")
|
|
||||||
(format t num-plus-newline)
|
|
||||||
(parse-integer num-plus-newline) ; junk in string "9\\n"
|
|
||||||
|
|
||||||
(mapcar (lambda (str) (cl-ppcre:split " " (string-trim str) )) (cl-ppcre:split "\\n" (cl-ppcre:regex-replace-all ":" *test-monkey-line* " ")))
|
|
||||||
;; and now to have all numbers be translated into numbers, and works into symbols
|
|
||||||
;; to get single list?
|
|
||||||
;; or list per line i suppose
|
|
||||||
|
|
||||||
;; from "macro and compilation.lisp"
|
|
||||||
;; but, we coult treat arguments as lists where we define marco
|
|
||||||
(defmacro mix-and-match-2 ((x1 y1) (x2 y2))
|
|
||||||
`(list '(,x1 ,y1)
|
|
||||||
'(,x1 ,y2)
|
|
||||||
'(,x2 ,y1)
|
|
||||||
'(,x2 ,y2)))
|
|
||||||
|
|
||||||
(mix-and-match-2 (fred wilma) (tony bony))
|
|
||||||
|
|
||||||
;; so could have defmacro that takes in 4 lists, each is a line parsed
|
|
||||||
(string-trim " :" " :hello: worls: ")
|
|
||||||
|
|
||||||
(mapcar (lambda (str)
|
|
||||||
(mapcar #'parse-integer-or-symbol (cl-ppcre:split " " (string-trim " " str)))) (cl-ppcre:split "\\n" *test-monkey-line*))
|
|
||||||
;; i could first for each line to (string-trim ":," lala) if convertable to number convert to number
|
|
||||||
;; and then all stringp upcase and intern
|
|
||||||
(parse-integer "7:hello" :junk-allowed t) ; cool
|
|
||||||
|
|
||||||
(parse-integer-or-symbol "7:")
|
|
||||||
(parse-integer-or-symbol "qer")
|
|
||||||
|
|
||||||
(defparameter *test-monkey-sexp* (line-to-sexp *test-monkey-line*))
|
|
||||||
|
|
||||||
|
|
||||||
((MONKEY 0)
|
|
||||||
(STARTING |ITEMS:| 79 98 101 66)
|
|
||||||
(|OPERATION:| NEW = OLD * 19)
|
|
||||||
(|TEST:| DIVISIBLE BY 23)
|
|
||||||
(IF |TRUE:| THROW TO MONKEY 2)
|
|
||||||
(IF |FALSE:| THROW TO MONKEY 3))
|
|
||||||
|
|
||||||
(defmacro monkey-struct-to-instance (((monkey ordering-number)
|
|
||||||
(starting items &rest inventory-list)
|
|
||||||
(operation new eq old operation operation-number)
|
|
||||||
(test divisible by divisible-number)
|
|
||||||
(test tru th to monk true-monkey-number)
|
|
||||||
(test fals th to monk false-monkey-number)))
|
|
||||||
`(list 'monkey ,ordering-number 'inventory ',inventory-list 'operation '(lambda (item) (,operation item ,operation-number)) 'test ,divisible-number))
|
|
||||||
|
|
||||||
(monkey-struct-to-instance *test-monkey-sexp*)
|
|
||||||
(monkey-struct-to-instance ((MONKEY 0)
|
|
||||||
(STARTING |ITEMS:| 79 98 101 66)
|
|
||||||
(|OPERATION:| NEW = OLD * 19)
|
|
||||||
(|TEST:| DIVISIBLE BY 23)
|
|
||||||
(IF |TRUE:| THROW TO MONKEY 2)
|
|
||||||
(IF |FALSE:| THROW TO MONKEY 3)))
|
|
||||||
|
|
||||||
(defmacro list-in-list (((first second) (third fourth)))
|
|
||||||
`(list ,second ,fourth))
|
|
||||||
(list-in-list ((1 2) ("hello" "world")))
|
|
||||||
|
|
||||||
(nsubst *test-monkey-sexp*)
|
|
||||||
|
|
||||||
;; maybe do another macro on top of macro then?
|
|
||||||
(defmacro put-struct-into-macro (my-macro var)
|
|
||||||
`(,my-macro ,(eval var)))
|
|
||||||
|
|
||||||
(put-struct-into-macro monkey-struct-to-instance *test-monkey-sexp*)
|
|
||||||
;; LOL, this is certainly not the way to go
|
|
||||||
|
|
||||||
|
|
||||||
;; after getting help from CL Matrix:
|
|
||||||
;; i need to use DESTRUCTURING-BIND
|
|
||||||
|
|
||||||
(defun monkey-struct-to-instance (monkey-struct)
|
|
||||||
(destructuring-bind
|
|
||||||
((monkey ordering-number)
|
|
||||||
(starting items &rest inventory-list)
|
|
||||||
(operation new eq old operation operation-number)
|
|
||||||
(test divisible by divisible-number)
|
|
||||||
(test tru th to monk true-monkey-number)
|
|
||||||
(test fals th to monk false-monkey-number)) monkey-struct
|
|
||||||
`(list 'monkey ,ordering-number 'inventory ',inventory-list 'operation '(lambda (item) (,operation item ,operation-number)) 'test ,divisible-number)))
|
|
||||||
|
|
||||||
|
|
||||||
(monkey-struct-to-instance *test-monkey-sexp*)
|
|
||||||
;; and there's METABANG-BIND facility
|
|
||||||
|
|
||||||
;; now - have monkey class. what would connect the different data about monkey
|
|
||||||
;; and after that - initialize the array. and write functions like "step" on the monkey and "round" on the array?
|
|
||||||
|
|
||||||
;; first - let's read in a paragraph at a time?
|
|
||||||
|
|
||||||
(defparameter *11-test-input* (cl-ppcre:split "\\n\\n" (uiop:read-file-string "day11-test.txt")))
|
|
||||||
;; yay. thank you Cookbook : https://lispcookbook.github.io/cl-cookbook/files.html Reading Files
|
|
||||||
(mapcar #'monkey-struct-to-instance (mapcar #'line-to-sexp *11-test-input*))
|
|
||||||
|
|
||||||
|
|
||||||
(funcall (new-from-old-function '+ 2 'old) 7)
|
|
||||||
|
|
||||||
;; here doing eval and defun, because macro just been inserting operand1 instead of symbod to which it references?
|
|
||||||
;; this is not good, but ok =C
|
|
||||||
|
|
||||||
(rem 7 3)
|
|
||||||
(mod 7 3)
|
|
||||||
|
|
||||||
(monkey-struct-to-instance *test-monkey-sexp*)
|
|
||||||
|
|
||||||
(defparameter *test-monkey-instance*
|
|
||||||
(make-instance 'monkey
|
|
||||||
:test (lambda (num) (if (= num 4) 1 2)) :operation (lambda (num) (+ num 1))
|
|
||||||
:inventory '(1 2 3) :number 4))
|
|
||||||
|
|
||||||
(funcall (test *test-monkey-instance*) 6)
|
|
||||||
;; and i don't really need the ordering-number, but ok
|
|
||||||
|
|
||||||
(defparameter *11-test-structs*
|
|
||||||
(coerce (mapcar #'monkey-struct-to-instance (mapcar #'line-to-sexp *11-test-input*)) 'vector))
|
|
||||||
|
|
||||||
;; now i want Turn and Round
|
|
||||||
;; turn - monkey iterates over all inventory.
|
|
||||||
;; inspects -
|
|
||||||
;; - apply Operation
|
|
||||||
;; - the worry / 3 ; default by player
|
|
||||||
;; - test -> return to which monkey to send
|
|
||||||
;;
|
|
||||||
;; i probably want to not tie up "turn" with array of monkeys
|
|
||||||
;; and only reference the array when codiyng up
|
|
||||||
;; round - each monkey gets a turn.
|
|
||||||
;; monkeys receive thrown items immediately when they are thrown
|
|
||||||
(lambda (worry) (* worry 13))
|
|
||||||
|
|
||||||
(funcall (slot-value (aref *11-test-structs* 2) 'operation) 5)
|
|
||||||
(let ((old 2)) (eval (funcall '* old old)))
|
|
||||||
(funcall (test (aref *11-test-structs* 0)) 23)
|
|
||||||
|
|
||||||
;; wow. some operations are new = old * old. wow. now that's not cool
|
|
||||||
;; but can be done i think
|
|
||||||
;; yup. only with macros i guess? and unhyginic?
|
|
||||||
;; and it works, but again with eval. to create lambda from the quoted description of lambda
|
|
||||||
|
|
||||||
;; and we're back to doing the turn?
|
|
||||||
;; or do i implement methods for monkey inspect and test? ugh
|
|
||||||
|
|
||||||
(defun monkey-one-item-action (monkey)
|
|
||||||
(let ((item-worry (first (inventory monkey) )))
|
|
||||||
(when item-worry
|
|
||||||
(setf (inventory monkey) (cdr (inventory monkey)))
|
|
||||||
(setq item-worry (funcall (operation monkey) item-worry))
|
|
||||||
;; (setq item-worry (floor (/ item-worry 3)))
|
|
||||||
(incf (slot-value monkey 'inspection-counter))
|
|
||||||
;; returning (target-monkey-num thrown-item)
|
|
||||||
(list (funcall (test monkey) item-worry) item-worry))))
|
|
||||||
|
|
||||||
(defparameter *test-monkey-instance*
|
|
||||||
(make-instance 'monkey
|
|
||||||
:test (lambda (num) (if (= num 4) 9 8)) :operation (lambda (num) (+ num 1))
|
|
||||||
:inventory '(100 60 30) :number 4
|
|
||||||
:mod 5))
|
|
||||||
(monkey-one-item-action *test-monkey-instance*)
|
|
||||||
(inspection-counter *test-monkey-instance*)
|
|
||||||
|
|
||||||
(defparameter *test-monkey-turn* (monkey-turn *test-monkey-instance*))
|
|
||||||
(alexandria:hash-table-alist *test-monkey-turn*) ; looks ok, but it still should be reversed?
|
|
||||||
|
|
||||||
(alexandria:maphash-values #'reverse *test-monkey-turn*)
|
|
||||||
(reverse (gethash 8 *test-monkey-turn*))
|
|
||||||
(maphash (lambda (key value-list) (setf (gethash key *test-monkey-turn*) (reverse (gethash key *test-monkey-turn*)))) *test-monkey-turn*)
|
|
||||||
;; so MAPHASH and MAPHASH-VALUES do not change hashmap, ugh
|
|
||||||
|
|
||||||
(defparameter *test-hash* (make-hash-table :test 'equal))
|
|
||||||
(defparameter *test-hash* '(1))
|
|
||||||
(push 11 (gethash "hello" *test-hash*))
|
|
||||||
(push 11 *test-hash*)
|
|
||||||
(setf (gethash "hello" *test-hash*) (push 11 (gethash "hello" *test-hash*)))
|
|
||||||
(setf (gethash "why" *test-hash*) 11)
|
|
||||||
;; wtf. why setf doesn't change content of hash key?
|
|
||||||
;; well, that's because I use `eq for comparison. hello
|
|
||||||
|
|
||||||
;; now have function for MONKEY-TURN, returning hashmap of transferred items
|
|
||||||
(append '(1 2 3) '(5 6))
|
|
||||||
|
|
||||||
|
|
||||||
;; and now yolo try to run 20 rounds on test monkey array?
|
|
||||||
|
|
||||||
;; wait. I also need to cound "how many items did each monkey inspected"
|
|
||||||
;; let's keep it for tomorrow, ugh
|
|
||||||
|
|
||||||
;; on the next task, i'll start separating my daily scratch and final code
|
|
||||||
;; it's too much noise between the code
|
|
||||||
;; ok, added that
|
|
||||||
|
|
||||||
(sort (mapcar #'inspection-counter (coerce *11-input-structs* 'list)) #'>)
|
|
||||||
;; 329 305
|
|
||||||
(* 329 305)
|
|
||||||
|
|
||||||
;;; PART 2.
|
|
||||||
|
|
||||||
;; let's just hardcode change to "releaf level change"
|
|
||||||
|
|
||||||
;; find another way to keep your worry levels manageable.
|
|
||||||
;; otherwise turns take really long time to compute.
|
|
||||||
;; what's important is to retain all TEST - so when i make numbers smaller, they have to keep all same MOD for all same test values.
|
|
||||||
|
|
||||||
;; so, what? let's go to sleep
|
|
||||||
;; now. if i read in all those "divisible by" so. what i want is to preserve MOD x
|
|
||||||
;; so, could get lowest common multiple and get mod from that? and set it in all monkeys,
|
|
||||||
;; or better - define it as class \ static attribute
|
|
||||||
|
|
||||||
(defparameter *11-input-paragraphs*
|
|
||||||
(cl-ppcre:split "\\n\\n" (uiop:read-file-string "day11-input.txt")))
|
|
||||||
|
|
||||||
(defparameter *11-input-structs* nil)
|
|
||||||
(defparameter *11-input-structs*
|
|
||||||
(coerce (mapcar #'monkey-struct-to-instance
|
|
||||||
(mapcar #'line-to-sexp *11-input-paragraphs*)) 'vector))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for monkey across *11-input-structs*
|
|
||||||
do (when (not (= 0 (mod (mod-reductor-2 monkey) (monkey-mod monkey))))
|
|
||||||
(setf (slot-value monkey 'mod-reductor-2) (* (mod-reductor-2 monkey) (monkey-mod monkey)))))
|
|
||||||
|
|
||||||
(mod 1 3)
|
|
||||||
(setf (slot-value *test-monkey-instance* 'mod-reductor-2) 1)
|
|
||||||
;; yep.
|
|
||||||
;; now need to take mod by this one? and then it will preserve mod by any of previous, right?
|
|
||||||
|
|
||||||
(mod (+ 9699690 177) 5)
|
|
||||||
(mod 177 5)
|
|
||||||
;; now substitute my worry by mod over "common multiple" and run 20k cycles
|
|
||||||
(mod 4 7)
|
|
||||||
|
|
||||||
(progn
|
|
||||||
(defparameter *11-test-input* (cl-ppcre:split "\\n\\n" (uiop:read-file-string "day11-test.txt")))
|
|
||||||
(defparameter *11-test-structs*
|
|
||||||
(coerce (mapcar #'monkey-struct-to-instance
|
|
||||||
(mapcar #'line-to-sexp *11-test-input*)) 'vector))
|
|
||||||
;; oh, i need to reset and recalculate the lowest common multiple for test input.
|
|
||||||
;; yup
|
|
||||||
(setf (slot-value *test-monkey-instance* 'mod-reductor-2) 1)
|
|
||||||
(loop
|
|
||||||
for monkey across *11-test-structs*
|
|
||||||
do (when (not (= 0 (mod (mod-reductor-2 monkey) (monkey-mod monkey))))
|
|
||||||
(setf (slot-value monkey 'mod-reductor-2) (* (mod-reductor-2 monkey) (monkey-mod monkey)))))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for i from 1 to 10000
|
|
||||||
do (progn (monkeys-round *11-test-structs*)
|
|
||||||
(format t "turn ~a~%" i)))
|
|
||||||
|
|
||||||
(print (apply #'* (subseq (sort
|
|
||||||
(mapcar #'inspection-counter
|
|
||||||
(coerce *11-test-structs* 'list)) #'>) 0 2)))
|
|
||||||
(setf (slot-value *test-monkey-instance* 'mod-reductor-2) 1))
|
|
||||||
|
|
||||||
;; yeah
|
|
@ -1,27 +0,0 @@
|
|||||||
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
|
|
179
day11.lisp
179
day11.lisp
@ -1,179 +0,0 @@
|
|||||||
;; monkeys https://adventofcode.com/2022/day/11
|
|
||||||
|
|
||||||
(require 'cl-ppcre)
|
|
||||||
(defun parse-integer-or-symbol (str)
|
|
||||||
(let ((maybe-int (parse-integer str :junk-allowed t)))
|
|
||||||
(if maybe-int
|
|
||||||
maybe-int
|
|
||||||
(intern (string-upcase str)))))
|
|
||||||
|
|
||||||
(defun line-to-sexp (line)
|
|
||||||
(mapcar (lambda (str)
|
|
||||||
(mapcar #'parse-integer-or-symbol (cl-ppcre:split " " (string-trim " " str))))
|
|
||||||
(cl-ppcre:split "\\n" line)))
|
|
||||||
|
|
||||||
|
|
||||||
(defun monkey-struct-to-instance (monkey-struct)
|
|
||||||
(destructuring-bind
|
|
||||||
((monkey ordering-number)
|
|
||||||
(starting items &rest inventory-list)
|
|
||||||
(operation new eq old operation operation-number)
|
|
||||||
(test divisible by divisible-number)
|
|
||||||
(test tru th to monk true-monkey-number)
|
|
||||||
(test fals th to monk false-monkey-number)) monkey-struct
|
|
||||||
`(list 'monkey ,ordering-number 'inventory ',inventory-list 'operation '(lambda (item) (,operation item ,operation-number)) 'test ,divisible-number)))
|
|
||||||
|
|
||||||
(defclass monkey ()
|
|
||||||
((order-number :reader order-number :initarg :number)
|
|
||||||
(inventory :accessor inventory :initarg :inventory)
|
|
||||||
(operation :reader operation :initarg :operation)
|
|
||||||
(test :reader test :initarg :test)
|
|
||||||
(inspection-counter :reader inspection-counter :initform 0)
|
|
||||||
(monkey-mod :reader monkey-mod :initarg :mod)
|
|
||||||
(mod-reductor-2 :reader mod-reductor-2 :initform 1 :allocation :class)))
|
|
||||||
|
|
||||||
(defmethod print-object ((obj monkey)
|
|
||||||
stream)
|
|
||||||
(print-unreadable-object (obj stream :type t)
|
|
||||||
(with-accessors ((order-number order-number )
|
|
||||||
(inventory inventory)
|
|
||||||
(inspection-counter inspection-counter)
|
|
||||||
(monkey-mod monkey-mod)
|
|
||||||
(mod-reductor-2 mod-reductor-2))
|
|
||||||
obj
|
|
||||||
(format stream "~a, with objects: ~a; count: ~a; mod: ~a; common: ~a"
|
|
||||||
order-number inventory inspection-counter monkey-mod mod-reductor-2))))
|
|
||||||
|
|
||||||
(defun new-from-old-function (operation operand1 operand2)
|
|
||||||
(eval `(lambda (old)
|
|
||||||
(,operation ,operand1 ,operand2)))) ; unhyginic macro
|
|
||||||
|
|
||||||
|
|
||||||
(defun monkey-struct-to-instance (monkey-struct)
|
|
||||||
(destructuring-bind
|
|
||||||
((monkey ordering-number)
|
|
||||||
(starting items &rest inventory-list)
|
|
||||||
(operation new eq operand1 operation-sign operand2)
|
|
||||||
(test divisible by divisible-number)
|
|
||||||
(test tru th to monk true-monkey-number)
|
|
||||||
(test fals th to monk false-monkey-number)) monkey-struct
|
|
||||||
(let ((operation-fun (new-from-old-function operation-sign operand1 operand2))
|
|
||||||
(test-fun (lambda (item-worry)
|
|
||||||
(if (= 0 (mod item-worry divisible-number))
|
|
||||||
true-monkey-number
|
|
||||||
false-monkey-number))))
|
|
||||||
(make-instance 'monkey
|
|
||||||
:test test-fun :operation operation-fun
|
|
||||||
:inventory inventory-list :number ordering-number
|
|
||||||
:mod divisible-number))))
|
|
||||||
|
|
||||||
(defun monkey-one-item-action (monkey)
|
|
||||||
(let ((item-worry (first (inventory monkey) )))
|
|
||||||
(when item-worry
|
|
||||||
(setf (inventory monkey) (cdr (inventory monkey)))
|
|
||||||
(setq item-worry (funcall (operation monkey) item-worry))
|
|
||||||
;; (setq item-worry (floor (/ item-worry 3)))
|
|
||||||
(setq item-worry (mod item-worry (mod-reductor-2 monkey)))
|
|
||||||
(incf (slot-value monkey 'inspection-counter))
|
|
||||||
;; returning (target-monkey-num thrown-item)
|
|
||||||
(list (funcall (test monkey) item-worry) item-worry))))
|
|
||||||
(ql:quickload 'alexandria)
|
|
||||||
|
|
||||||
(defun monkey-turn (monkey)
|
|
||||||
(let ((thrown-hash (make-hash-table :test 'equal)))
|
|
||||||
(loop
|
|
||||||
for i from 1 to (length (inventory monkey))
|
|
||||||
do (let ((throw-result (monkey-one-item-action monkey)))
|
|
||||||
;; (format t "~s ~%" throw-result)
|
|
||||||
(setf (gethash (first throw-result) thrown-hash) (push (second throw-result) (gethash (first throw-result) thrown-hash)))))
|
|
||||||
(maphash (lambda (key value-list) (setf (gethash key thrown-hash) (reverse (gethash key thrown-hash)))) thrown-hash)
|
|
||||||
thrown-hash))
|
|
||||||
;; returns hashmap of which values go where
|
|
||||||
|
|
||||||
(defun monkeys-round (monkey-array)
|
|
||||||
;; for each monkey from array:
|
|
||||||
;; do it's turn, then for each record in resulting hashmap append list of transferred items to correct monkey
|
|
||||||
(loop
|
|
||||||
for monkey across monkey-array
|
|
||||||
do (let ((turn-result (monkey-turn monkey)))
|
|
||||||
(maphash
|
|
||||||
(lambda (target-monkey-num items-list)
|
|
||||||
(setf (inventory (aref monkey-array target-monkey-num)) (append (inventory (aref monkey-array target-monkey-num)) items-list)))
|
|
||||||
turn-result))))
|
|
||||||
|
|
||||||
(progn
|
|
||||||
(defparameter *11-test-structs*
|
|
||||||
(coerce (mapcar #'monkey-struct-to-instance (mapcar #'line-to-sexp *11-test-input*)) 'vector))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for i from 1 to 20
|
|
||||||
do (monkeys-round *11-test-structs*))
|
|
||||||
|
|
||||||
(sort (mapcar #'inspection-counter (coerce *11-test-structs* 'list)) #'>))
|
|
||||||
|
|
||||||
;; PART 1 on input data
|
|
||||||
|
|
||||||
(progn
|
|
||||||
(defparameter *11-input-paragraphs* (cl-ppcre:split "\\n\\n" (uiop:read-file-string "day11-input.txt")))
|
|
||||||
|
|
||||||
(defparameter *11-input-structs*
|
|
||||||
(coerce (mapcar #'monkey-struct-to-instance (mapcar #'line-to-sexp *11-input-paragraphs*)) 'vector))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for i from 1 to 20
|
|
||||||
do (progn (monkeys-round *11-input-structs*)
|
|
||||||
(format t "turn ~a~%" i)))
|
|
||||||
|
|
||||||
(apply #'* (subseq (sort (mapcar #'inspection-counter (coerce *11-input-structs* 'list)) #'>) 0 2)))
|
|
||||||
|
|
||||||
;;; PART 2.
|
|
||||||
(progn
|
|
||||||
(defparameter *11-test-input* (cl-ppcre:split "\\n\\n" (uiop:read-file-string "day11-test.txt")))
|
|
||||||
(defparameter *11-test-structs*
|
|
||||||
(coerce (mapcar #'monkey-struct-to-instance
|
|
||||||
(mapcar #'line-to-sexp *11-test-input*)) 'vector))
|
|
||||||
;; oh, i need to reset and recalculate the lowest common multiple for test input.
|
|
||||||
;; yup
|
|
||||||
(setf (slot-value *test-monkey-instance* 'mod-reductor-2) 1)
|
|
||||||
(loop
|
|
||||||
for monkey across *11-test-structs*
|
|
||||||
do (when (not (= 0 (mod (mod-reductor-2 monkey) (monkey-mod monkey))))
|
|
||||||
(setf (slot-value monkey 'mod-reductor-2) (* (mod-reductor-2 monkey) (monkey-mod monkey)))))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for i from 1 to 10000
|
|
||||||
do (progn (monkeys-round *11-test-structs*)
|
|
||||||
(format t "turn ~a~%" i)))
|
|
||||||
|
|
||||||
(print (apply #'* (subseq (sort
|
|
||||||
(mapcar #'inspection-counter
|
|
||||||
(coerce *11-test-structs* 'list)) #'>) 0 2)))
|
|
||||||
;; that's the problem with sharing slots across class
|
|
||||||
(setf (slot-value *test-monkey-instance* 'mod-reductor-2) 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
(progn
|
|
||||||
(defparameter *11-input-input*
|
|
||||||
(cl-ppcre:split "\\n\\n" (uiop:read-file-string "day11-input.txt")))
|
|
||||||
(defparameter *11-input-structs*
|
|
||||||
(coerce (mapcar #'monkey-struct-to-instance
|
|
||||||
(mapcar #'line-to-sexp *11-input-input*)) 'vector))
|
|
||||||
;; oh, i need to reset and recalculate the lowest common multiple for test input.
|
|
||||||
;; yup
|
|
||||||
(setf (slot-value *test-monkey-instance* 'mod-reductor-2) 1)
|
|
||||||
(loop
|
|
||||||
for monkey across *11-input-structs*
|
|
||||||
do (when (not (= 0 (mod (mod-reductor-2 monkey) (monkey-mod monkey))))
|
|
||||||
(setf (slot-value monkey 'mod-reductor-2) (* (mod-reductor-2 monkey) (monkey-mod monkey)))))
|
|
||||||
|
|
||||||
(loop
|
|
||||||
for i from 1 to 10000
|
|
||||||
do (progn (monkeys-round *11-input-structs*)
|
|
||||||
(format t "turn ~a~%" i)))
|
|
||||||
|
|
||||||
(print (apply #'* (subseq (sort
|
|
||||||
(mapcar #'inspection-counter
|
|
||||||
(coerce *11-input-structs* 'list)) #'>) 0 2)))
|
|
||||||
;; that's the problem with sharing slots across class
|
|
||||||
(setf (slot-value *test-monkey-instance* 'mod-reductor-2) 1)
|
|
||||||
)
|
|
Loading…
x
Reference in New Issue
Block a user