diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-12-11 22:08:05 +0100 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-12-11 22:08:05 +0100 |
commit | 3d9604914eed388c9023c4029157e789c39bb23d (patch) | |
tree | 29eaa937526a5726f0d58dd1e3859a5bc71bab68 | |
parent | b6e0579074f22f25055acac1077154fbc5af9115 (diff) |
Refactor
-rw-r--r-- | 2024/11/puzzles.lisp | 42 |
1 files changed, 18 insertions, 24 deletions
diff --git a/2024/11/puzzles.lisp b/2024/11/puzzles.lisp index 9c3c73b..7d44a0b 100644 --- a/2024/11/puzzles.lisp +++ b/2024/11/puzzles.lisp @@ -3,9 +3,8 @@ (defparameter *memo* (make-hash-table :test 'equal)) (defun main (filename blink-count) - (let ((stones (read-stones filename))) - (loop for stone in stones - sum (count-stones stone blink-count)))) + (loop for stone in (read-stones filename) + sum (count-stones stone blink-count))) (defun read-stones (filename) (with-open-file (stream filename) @@ -14,33 +13,28 @@ (read-from-string (concatenate 'string "(" contents ")"))))) (defun count-stones (stone blink-count) - (or (gethash (cons stone blink-count) *memo*) - (setf (gethash (cons stone blink-count) *memo*) - (cond ((= (decf blink-count) -1) - 1) - ((= stone 0) - (count-stones 1 blink-count)) - ((evenp (integer-digit-count stone)) - (let ((hi-lo (integer-split stone))) - (+ (count-stones (car hi-lo) blink-count) - (count-stones (cdr hi-lo) blink-count)))) - (:else - (count-stones (* 2024 stone) blink-count)))))) + (let ((stone+blink-count (cons stone blink-count))) + (or (gethash stone+blink-count *memo*) + (setf (gethash stone+blink-count *memo*) + (cond ((minusp (decf blink-count)) + 1) + ((zerop stone) + (count-stones 1 blink-count)) + ((evenp (integer-digit-count stone)) + (multiple-value-bind (hi lo) (integer-split stone) + (+ (count-stones hi blink-count) + (count-stones lo blink-count)))) + (:else + (count-stones (* 2024 stone) blink-count))))))) (defun integer-digit-count (x) - (loop with n = 0 - while (/= x 0) - do (progn (incf n) (setq x (floor x 10))) - finally (return n))) + (1+ (truncate (log x 10)))) (defun integer-split (x) - (let* ((n (floor (integer-digit-count x) 2)) - (m (expt 10 n))) - (cons (floor x m) - (mod x m)))) + (floor x (expt 10 (floor (integer-digit-count x) 2)))) ;; START PART 1 (format t "~d~%" (main "input" 25)) ;; END PART 1 START PART 2 (format t "~d~%" (main "input" 75)) -;; END PART 2
\ No newline at end of file +;; END PART 2 |