diff options
Diffstat (limited to 'AoC2022/19')
-rw-r--r-- | AoC2022/19/solver.lisp | 60 |
1 files changed, 16 insertions, 44 deletions
diff --git a/AoC2022/19/solver.lisp b/AoC2022/19/solver.lisp index 37b1e74..083a093 100644 --- a/AoC2022/19/solver.lisp +++ b/AoC2022/19/solver.lisp @@ -29,39 +29,6 @@ (defun bot-requirements (type recipes) (fset:lookup recipes type)) -(defun plist-merge (func p1 p2 &optional default) - "Merge 2 flat plists P1 & P2 by FUNC. Use DEFAULT when value is missing on one list." - (flet ((keys (plist) (loop for key in plist by #'cddr collect key))) - (loop for key in (union (keys p1) (keys p2)) - nconc (list key (funcall func (getf p1 key default) (getf p2 key default)))))) - -(defun max-costs (blueprint) - (reduce - (lambda (acc item) - (plist-merge #'max acc item 0)) - (mapcar #'cdr blueprint))) - -(defun can-build (recipes available-materials) - (mapcan (lambda (bot-recipes) - (when (can-build-robot-p (cdr bot-recipes) available-materials) - (list (car bot-recipes)))) - recipes)) - -(defun should-build (blueprints robots) - (let ((max-cost (max-costs blueprints))) - (loop for (type amount) on robots by #'cddr - when (or (eq type :geode) - (<= amount (getf max-cost type 0))) - collect type))) - -(defun try! (build-next robots resources blueprints) - (let ((req (bot-requirements build-next blueprints))) - (if (can-build-robot-p req resources) - (values - (consume req resources) - (fset:with robots build-next)) - (values resources robots)))) - (defun next-step (build-next robots resources blueprints time-left) (if (zerop time-left) ;; (list robots resources) @@ -69,19 +36,26 @@ ;; resources (let ((req (bot-requirements build-next blueprints))) (if (can-build-robot-p req resources) - (reduce (lambda (max next) - (max max - (next-step next - (fset:with robots build-next) - (material-collect robots (consume req resources)) - blueprints (1- time-left)))) - '(:geode :obsidian :clay :ore) - :initial-value 0) + (let ((new-robots (fset:with robots build-next)) + (resources-left (consume req resources))) + (probe new-robots + (material-collect robots resources-left) + blueprints (1- time-left))) (next-step build-next robots (material-collect robots resources) blueprints (1- time-left)))))) +(defun probe (robots resources blueprints time-left) + (reduce (lambda (max next) + (max max + (next-step next + robots + resources + blueprints time-left))) + '(:geode :obsidian :clay :ore) + :initial-value 0)) + (defun start-resources () ;; (list :ore 0 :clay 0 :obsidian 0 :geode 0) (fset:empty-bag)) @@ -103,7 +77,5 @@ (bots (start-bots)) ;; (bots '(:geode 1 :ore 8 :clay 20)) (time-left 24)) - - - (next-step :clay bots materials blueprints time-left) + (probe bots materials blueprints time-left) ) |