ITMNMCQXRXSBLHQZQNXT2R6OHKABVCNKM6KGCCCUC7TVS6PHKNRAC (defun process (instream)(loop for line = (read-line instream nil) while line sum(calibration line)))
(defgeneric push-char (accumulator value)(:documentation "Process a character from the input."))(defgeneric peek (accumulator)(:documentation "Determine whether or not a \"digit\" has been found."))(defclass digit-accumulator ()((current-digit :initform nil)))(defmethod push-char ((accumulator digit-accumulator) value)(setf (slot-value accumulator 'current-digit) (digit-char-p value)))(defmethod peek ((accumulator digit-accumulator))(slot-value accumulator 'current-digit))(defclass english-accumulator ()((matching :initform nil)))(defconstant english-numbers(append (let ((ix 0))(mapcar #'(lambda (name) (incf ix) (append (coerce name 'list) ix))'("one" "two" "three" "four" "five""six" "seven" "eight" "nine" "ten")))(loopfor n from 1 to 9collect (append (coerce (format nil "~a" n) 'list) n))))(defmethod push-char ((accumulator english-accumulator) value)(setf (slot-value accumulator 'matching)(mapcan#'(lambda (entry)(if (and (consp entry) (equal value (car entry)))(list (cdr entry))))(append (slot-value accumulator 'matching) english-numbers))))
(let ((a NIL) (b NIL))(loop for c across line do (let ((x (digit-char-p c)))(when x (setq b x) (unless a (setq a x)))))(when (and a b) (+ (* 10 a) b))))
(let ((accs(mapcar#'(lambda (which)(list 'accumulator (make-instance which)'low () 'high ()))'(digit-accumulator english-accumulator))))(loop for c across linedo (dolist (ac accs)(push-char (getf ac 'accumulator) c)(let ((digit (peek (getf ac 'accumulator))))(when digit(setf (getf ac 'high) digit)(unless (getf ac 'low) (setf (getf ac 'low) digit))))))(mapcar#'(lambda (acc)(let ((low (getf acc 'low)) (high (getf acc 'high)))(when (and low high) (+ (* 10 low) high))))accs)))(defun process (instream)(let ((p1 0) (p2 0))(loop for line = (read-line instream nil)while linedo (destructuring-bind(p1-1 p2-1)(calibration line)(setf p1 (+ p1 p1-1))(setf p2 (+ p2 p2-1))))(list p1 p2)))
(loop for arg in (cdr *posix-argv*) do(with-open-file (s arg :direction :input) (format T "~d~&" (process s))))
(loop for arg in (cdr *posix-argv*)do (with-open-file (s arg :direction :input)(loop for result in (process s)for part from 1do (format T "Part ~a: ~a~%" part result))))