adventofcode2022

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

commit 702ea36107882b4d56a497bf0c1abba77d066d4c
parent 6b3d21d10f030a72d278a2596d24eff6572a8f59
Author: Lukas Henkel <lh@entf.net>
Date:   Wed, 21 Dec 2022 22:19:26 +0100

Bruteforce day 21 task 2

Diffstat:
Msrc/day21.lisp | 99++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Mt/day21.lisp | 6++++++
2 files changed, 84 insertions(+), 21 deletions(-)

diff --git a/src/day21.lisp b/src/day21.lisp @@ -2,33 +2,90 @@ (:use #:cl #:adventofcode2022)) (in-package #:adventofcode2022/day21) -(defun cache-monkey (monkey) - (let ((cache)) - (lambda (monkeys) - (if cache - cache - (setf cache (funcall monkey monkeys)))))) +(defparameter *yell-operations* (make-hash-table)) +(setf (gethash :+ *yell-operations*) #'+) +(setf (gethash :- *yell-operations*) #'-) +(setf (gethash :* *yell-operations*) #'*) +(setf (gethash :/ *yell-operations*) #'/) + +(defparameter *yell-operations-reverse* (make-hash-table)) +(setf (gethash :+ *yell-operations-reverse*) #'-) +(setf (gethash :- *yell-operations-reverse*) #'+) +(setf (gethash :* *yell-operations-reverse*) #'/) +(setf (gethash :/ *yell-operations-reverse*) #'*) + +(defun monkey-yell (monkey monkeys) + (if (listp monkey) + (destructuring-bind (op monkey-1 monkey-2) + monkey + (let ((dep-1 (monkey-yell (gethash monkey-1 monkeys) monkeys)) + (dep-2 (monkey-yell (gethash monkey-2 monkeys) monkeys)) + (op-fun (gethash op *yell-operations*))) + (funcall op-fun dep-1 dep-2))) + monkey)) + +(defun monkey-yell-reverse (monkey monkeys monkey-deps) + "This only works for the example, no idea why, maybe I'll debug this some other day." + (let* ((dep-monkey-name (gethash monkey monkey-deps)) + (dep-monkey-rule (gethash dep-monkey-name monkeys)) + (dep-monkey-op (gethash (car dep-monkey-rule) *yell-operations-reverse*)) + (dep-monkey-deps (cdr dep-monkey-rule)) + (dep-monkey-other-monkey-car? (= 0 (position monkey dep-monkey-deps))) + (dep-monkey-other-monkey (car (remove monkey dep-monkey-deps)))) + (cond + ((eq dep-monkey-name :root) + (monkey-yell (gethash dep-monkey-other-monkey monkeys) monkeys)) + (t (let ((args (list + (monkey-yell-reverse dep-monkey-name monkeys monkey-deps) + (monkey-yell (gethash dep-monkey-other-monkey monkeys) monkeys)))) + (when dep-monkey-other-monkey-car? + (setf args (reverse args))) + (apply dep-monkey-op args)))))) (defun task1 (inputs) - (let ((monkeys (make-hash-table :test 'equal))) + (let ((monkeys (make-hash-table))) + (loop for (name monkey) in inputs + do (setf (gethash name monkeys) monkey)) + (monkey-yell (gethash :root monkeys) monkeys))) + +#|(defun task2 (inputs) +(let ((monkeys (make-hash-table)) +(monkey-deps (make-hash-table))) +(loop for (name monkey) in inputs +do (setf (gethash name monkeys) monkey) +when (consp monkey) +do (loop for dep in (cdr monkey) +do (setf (gethash dep monkey-deps) name))) +(monkey-yell-reverse :humn monkeys monkey-deps)))|# + +(defun task2 (inputs) + (let ((monkeys (make-hash-table))) (loop for (name monkey) in inputs - do (setf (gethash name monkeys) (cache-monkey monkey))) - (funcall (gethash "root" monkeys) monkeys))) + do (setf (gethash name monkeys) monkey)) + (let ((root (gethash :root monkeys))) + (setf (car root) :-) + (loop for inc = 1000000000 then (floor inc 10) + while (> inc 0) + thereis (loop for res = (monkey-yell root monkeys) + thereis (= res 0) + when (< res 0) + do (setf (gethash :humn monkeys) (- (gethash :humn monkeys) inc)) + and return nil + while (> res 0) + do (setf (gethash :humn monkeys) (+ (gethash :humn monkeys) inc)))) + (gethash :humn monkeys)))) (define-day 21 (:translate-input (lambda (line) (destructuring-bind (name rule) (str:split ": " line) - (list name - (eval `(lambda (monkeys) - ,@(if (str:containsp " " rule) - (destructuring-bind (monkey-1 op monkey-2) - (str:split " " rule) - (list `(,(intern op) - (funcall (gethash ,monkey-1 monkeys) monkeys) - (funcall (gethash ,monkey-2 monkeys) monkeys)))) - (list - '(declare (ignore monkeys)) - (parse-integer rule))))))))) + (list (intern (str:upcase name) :keyword) + (if (str:containsp " " rule) + (destructuring-bind (monkey-1 op monkey-2) + (str:split " " rule) + (list (intern op :keyword) + (intern (str:upcase monkey-1) :keyword) + (intern (str:upcase monkey-2) :keyword))) + (parse-integer rule)))))) #'task1 - nil) + #'task2) diff --git a/t/day21.lisp b/t/day21.lisp @@ -22,3 +22,9 @@ hmdt: 32" (= 152 (run-task 21 1 (make-string-input-stream +testdata-day21+))))) + +(def-test day21-task2 () + (is-true + (= 301 + (run-task 21 2 + (make-string-input-stream +testdata-day21+)))))