blob: 9c3c73b17323d3192ed44b1120165eb03748df11 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
#!/usr/bin/sbcl --script
(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))))
(defun read-stones (filename)
(with-open-file (stream filename)
(let ((contents (make-string (file-length stream))))
(read-sequence contents stream)
(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))))))
(defun integer-digit-count (x)
(loop with n = 0
while (/= x 0)
do (progn (incf n) (setq x (floor x 10)))
finally (return n)))
(defun integer-split (x)
(let* ((n (floor (integer-digit-count x) 2))
(m (expt 10 n)))
(cons (floor x m)
(mod x m))))
;; START PART 1
(format t "~d~%" (main "input" 25))
;; END PART 1 START PART 2
(format t "~d~%" (main "input" 75))
;; END PART 2
|