(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")))