Advent of Code 2021 solutions
(ql:quickload "split-sequence")

(defun read-data (path)
  (with-open-file (stream path)
                  (loop for line = (read-line stream nil)
                        while line collect line)))

(defparameter *input-source*
  (cadr *posix-argv*))

;; Useful in testing
;; (defparameter *input-source* "example_input")
;; (defparameter *input-source* "input")

(defun parse-input (lines)
  (map 'list #'parse-integer
       (split-sequence:split-sequence #\, (car lines))))

(defun preprocess-input (numbers)
  (let ((arr (make-array 9)))
    (dolist (n numbers)
      (setf (aref arr n) (1+ (aref arr n))))
    arr))

(defparameter *data*
  (parse-input (read-data *input-source*)))

(defun solution (data days)
  (let ((working (preprocess-input data)))
    (dotimes (offset (1+ days))
      (setf (aref working (mod (+ offset 6) 9)) (+ (aref working (mod (+ offset 8) 9))
                                                   (aref working (mod (+ offset 6) 9)))))
    (loop for x from 0 to 8 sum (aref working x))))

(defun part1 (data)
  (solution data 80))

(defun part2 (data)
  (solution data 256))

(format t "===== Part 1 =====")
(format t "Result: ~A~%~%" (time (part1 *data*)))

(format t "===== Part 2 =====")
(format t "Result: ~A~%" (time (part2 *data*)))