2023 day 1
This commit is contained in:
commit
d598c40185
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.fasl
|
||||
data.txt
|
46
2023/1/Main.hs
Normal file
46
2023/1/Main.hs
Normal file
|
@ -0,0 +1,46 @@
|
|||
import Data.Char (isDigit, digitToInt)
|
||||
import Data.Function (on)
|
||||
import Data.List (tails, findIndex, isPrefixOf, minimumBy)
|
||||
import Data.Maybe (mapMaybe)
|
||||
import Data.Bifunctor (first)
|
||||
|
||||
type LineOp = String -> Int
|
||||
|
||||
wordMap :: [(String, Int)]
|
||||
wordMap = [ ("one", 1)
|
||||
, ("two", 2)
|
||||
, ("three", 3)
|
||||
, ("four", 4)
|
||||
, ("five", 5)
|
||||
, ("six", 6)
|
||||
, ("seven", 7)
|
||||
, ("eight", 8)
|
||||
, ("nine", 9)
|
||||
]
|
||||
|
||||
fullWordMap :: [(String, Int)]
|
||||
fullWordMap = wordMap ++ (zip =<< map show) [1..9]
|
||||
|
||||
opLineBasic :: LineOp
|
||||
opLineBasic l = (combineDigits `on` ($ digitToInt <$> filter isDigit l)) head last
|
||||
|
||||
firstNumInLine :: String -> [(String, Int)] -> Int
|
||||
firstNumInLine l = fst . minimumBy (compare `on` snd) . mapMaybe numIndex
|
||||
where
|
||||
numIndex (str, num) = (num,) <$> findIndex (isPrefixOf str) (tails l)
|
||||
|
||||
opLineAdvanced :: LineOp
|
||||
opLineAdvanced l = (combineDigits `on` uncurry firstNumInLine)
|
||||
(l, fullWordMap)
|
||||
(reverse l, first reverse <$> fullWordMap)
|
||||
|
||||
combineDigits :: Int -> Int -> Int
|
||||
combineDigits = (+) . (10 *)
|
||||
|
||||
opLines :: [String] -> Int
|
||||
opLines = sum . map opLineAdvanced
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
content <- readFile "data.txt"
|
||||
print . opLines . lines $ content
|
23
2023/1/main-1.lisp
Normal file
23
2023/1/main-1.lisp
Normal file
|
@ -0,0 +1,23 @@
|
|||
(defpackage #:aoc-2023/1.1
|
||||
(:use #:cl)
|
||||
(:export #:main))
|
||||
|
||||
(in-package #:aoc-2023/1.1)
|
||||
|
||||
(defun digits-to-integer (a b)
|
||||
(values (parse-integer (format NIL "~A~A" a b))))
|
||||
|
||||
(defun line-value (line)
|
||||
(digits-to-integer (find-if #'digit-char-p line)
|
||||
(find-if #'digit-char-p line :from-end T)))
|
||||
|
||||
(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))
|
48
2023/1/main-2.lisp
Normal file
48
2023/1/main-2.lisp
Normal file
|
@ -0,0 +1,48 @@
|
|||
(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))
|
Loading…
Reference in a new issue