advent-of-code/2023/haskell/solutions/Day01.hs
2023-12-01 23:03:57 +01:00

54 lines
1.3 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
module Day01 (parse, solveA, solveB) where
import qualified Data.Text as T
import Data.Text (Text)
import Data.Char (isDigit)
import Data.Maybe (mapMaybe, listToMaybe)
parse :: Text -> [Text]
parse = T.lines
merge :: [Int] -> Int
merge xs = 10 * head xs + last xs
solveA :: [Text] -> Int
solveA = sum . map (merge . convert)
where
convert :: Text -> [Int]
convert = map (read . pure) . T.unpack . T.filter isDigit
replaces :: [(Text, Int)]
replaces =
[ ("one", 1)
, ("two", 2)
, ("three", 3)
, ("four", 4)
, ("five", 5)
, ("six", 6)
, ("seven", 7)
, ("eight", 8)
, ("nine", 9)
]
solveB :: [Text] -> Int
solveB = sum . map (merge . convert)
where
-- If `text` starts with `prefix` return `Just n`, otherwise return `Nothing`
tryReplace :: Text -> (Text, Int) -> Maybe Int
tryReplace text (prefix, n)
| prefix `T.isPrefixOf` text = Just n
| otherwise = Nothing
-- If `firstChar` is a digit return it, otherwise try replace the prefix
parsePrefix :: Text -> Maybe Int
parsePrefix text
| isDigit firstChar = Just . read . pure $ firstChar
| otherwise = listToMaybe $ mapMaybe (tryReplace text) replaces
where
firstChar = T.head text
convert :: Text -> [Int]
convert = mapMaybe parsePrefix . filter (not . T.null) . T.tails