(defun input-lines (f) (with-open-file (s f) (loop for line = (read-line s nil 'eof) until (eq line 'eof) collect line))) (defun collect-line-digits (line) (loop for char across line if (digit-char-p char) collect (digit-char-p char))) (defun calibration-value (numbers) (let ((fst (first numbers)) (lst (car (last numbers)))) (+ (* 10 fst) lst))) (defun calibration-values (lnumbers) (mapcar #'calibration-value lnumbers)) (defun solve1 (f) (let ((lnumbers (mapcar #'collect-line-digits (input-lines f)))) (reduce #'+ (calibration-values lnumbers)))) (defun string-compare (s1 s2 begin) (let ((l1 (array-total-size s1)) (l2 (- (array-total-size s2) begin))) (if (>= l2 l1) (equalp s1 (subseq s2 begin (+ begin l1)))))) (defun string-digit-text-p (s begin) (cond ((string-compare "zero" s begin) 0) ((string-compare "one" s begin) 1) ((string-compare "two" s begin) 2) ((string-compare "three" s begin) 3) ((string-compare "four" s begin) 4) ((string-compare "five" s begin) 5) ((string-compare "six" s begin) 6) ((string-compare "seven" s begin) 7) ((string-compare "eight" s begin) 8) ((string-compare "nine" s begin) 9))) (defun string-digit-p (s begin) (let ((digit (digit-char-p (aref s begin)))) (if digit digit (string-digit-text-p s begin)))) (defun collect-line-digits2 (line) (loop with l = (array-total-size line) for i from 0 to (- l 1) as d = (string-digit-p line i) when d collect d)) (defun solve2 (f) (let ((lnumbers (mapcar #'collect-line-digits2 (input-lines f)))) (reduce #'+ (calibration-values lnumbers)))) (print (solve1 "data/01/example1.txt")) (print (solve1 "data/01/input.txt")) (print (solve2 "data/01/example2.txt")) (print (solve2 "data/01/input.txt"))