(require :uiop) (defun split-instruction (s) (cons (intern (subseq s 0 1)) (parse-integer (subseq s 1)))) (defun turn-dial (dial instruction) (let ((cons-instruction (split-instruction instruction))) (let ((op (car cons-instruction)) (amount (cdr cons-instruction))) (mod (funcall (cond ((eql 'L op) #'-) ((eql 'R op) #'+) (t (error "unknown op"))) dial amount) 100) ) )) ;; (turn-dial 50 "L68") ;; (turn-dial 82 "L30") ;; (turn-dial 52 "R48") ;; (turn-dial 0 "L5") ;; (turn-dial 95 "R60") ;; (turn-dial 55 "L55") ;; (turn-dial 0 "L1") ;; (turn-dial 99 "L99") ;; (turn-dial 0 "R14") ;; (turn-dial 14 "L82") (defun rec-dial-vm (accum dial lines) (let ((instruction (pop lines))) (if instruction (let ((new-dial (turn-dial dial instruction))) ;(format t "~A ~A -> ~A ~%" dial instruction new-dial) (if (= new-dial 0) (rec-dial-vm (+ 1 accum) new-dial lines) (rec-dial-vm accum new-dial lines))) accum))) (rec-dial-vm 0 50 (uiop:read-file-lines "01example.txt")) (rec-dial-vm 0 50 (uiop:read-file-lines "01data.txt"))