49 lines
1.5 KiB
Common Lisp
49 lines
1.5 KiB
Common Lisp
(defpackage #:aoc-2023/1.2
|
|
(:use #:cl)
|
|
(:export #:main))
|
|
|
|
(in-package #:aoc-2023/1.2)
|
|
|
|
(defparameter *numbers* '(("one" . 1)
|
|
("two" . 2)
|
|
("three" . 3)
|
|
("four" . 4)
|
|
("five" . 5)
|
|
("six" . 6)
|
|
("seven" . 7)
|
|
("eight" . 8)
|
|
("nine" . 9)))
|
|
|
|
(defun digits-to-integer (a b)
|
|
(values (parse-integer (format NIL "~A~A" a b))))
|
|
|
|
(defun line-value (line)
|
|
(let* ((first-i (position-if #'digit-char-p line))
|
|
(last-i (position-if #'digit-char-p line :from-end T))
|
|
(first-val (when first-i (aref line first-i)))
|
|
(last-val (when last-i (aref line last-i))))
|
|
(loop :for (str . num) :in *numbers*
|
|
:for first := (search str line)
|
|
:for last := (search str line :from-end T)
|
|
:when first
|
|
:do (when (or (null first-i)
|
|
(< first first-i))
|
|
(setf first-i first)
|
|
(setf first-val num))
|
|
(when (or (null last-i)
|
|
(> last last-i))
|
|
(setf last-i last)
|
|
(setf last-val num)))
|
|
(digits-to-integer first-val last-val)))
|
|
|
|
(defun main ()
|
|
(format T
|
|
"~A~%"
|
|
(loop :for line := (read-line T NIL)
|
|
:while line
|
|
:unless (string= line "")
|
|
:sum (line-value line))))
|
|
|
|
(eval-when (:execute)
|
|
(main))
|