aboutsummaryrefslogtreecommitdiff
path: root/2024/11/puzzle-1.lisp
blob: 3fc7df74c2429b3665f14b85bd5cdd498927f9a9 (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
47
48
49
50
51
#!/usr/bin/sbcl --script

(defparameter *numbers*
  '())

(defun main (filename)
  (setq *numbers* (read-stones filename))
  (loop repeat 25
        do (blink)
        finally (return (length *numbers*))))

(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 blink ()
  (setq *numbers*
        (loop for number in *numbers*
              for after-blink = (stone-change-or-split number)
              if (listp after-blink)
                append after-blink
              else
                collect after-blink
              finally (setq *numbers* after-blink))))

(defun stone-change-or-split (number)
  (cond ((= number 0)
         1)
        ((evenp (digit-count number))
         (number-split number))
        (:else
         (* 2024 number))))

(defun digit-count (number)
  (loop with x = 0
        while (/= number 0)
        do (progn
             (incf x)
             (setq number (floor number 10)))
        finally (return x)))

(defun number-split (number)
  (let* ((length (digit-count number))
         (string (write-to-string number))
         (half (/ length 2)))
    (list (parse-integer (subseq string 0 half))
          (parse-integer (subseq string half (length string))))))

(format t "~d~%" (main "input"))