(defpackage aoc2025-day1
  (:nicknames day1)
  (:export main reload))

(in-package aoc2025-day1)

(defun parse-turn (line)
  (let ((distance (parse-integer (subseq line 1)))
        (direction (ecase (char-upcase (aref line 0))
                     (#\R :r)
                     (#\L :l))))
    (ecase direction
      (:r distance)
      (:l (- 0 distance)))))

(defclass dial-state ()
  ((value :initarg :value
          :type (integer 0 99))))

(defun zero-ticks (y)
  (floor (/ (max y (- 100 y)) 100)))

(defun turn (state line)
  (let* ((x (slot-value state 'value))
         (y (+ x (parse-turn line)))
         (z (mod y 100)))
    (setf (slot-value state 'value) z)
    (if (= x 0) (setf y (abs y)))
    (zero-ticks y)))

(defun main (filename)
  (with-open-file (input filename :direction :input)
    (let ((state (make-instance 'dial-state :value 50))
          (p1 0)
          (p2 0))
      (loop for line = (read-line input nil nil)
            while line
            do (if (/= 0 (array-dimension line 0))
                 (progn
                   (incf p2 (turn state line))
                   (if (= 0 (slot-value state 'value))
                     (incf p1)))))
      (format t "Part 1: ~A~%Part 2: ~A~%" p1 p2))))

(defun reload ()
  (delete-package :aoc2025-day1)
  (load (compile-file "day1.lisp")))