advent-of-code/2023/1/Main.hs

49 lines
1.3 KiB
Haskell
Raw Normal View History

2023-12-12 20:25:25 -08:00
{-# LANGUAGE TupleSections #-}
import Data.Char (isDigit, digitToInt)
import Data.Function (on)
import Data.List (tails, findIndex, isPrefixOf, minimumBy)
import Data.Maybe (mapMaybe)
import Data.Bifunctor (first, bimap)
2023-12-01 22:41:12 -08:00
type LineOp = String -> Int
wordMap :: [(String, Int)]
wordMap = [ ("one", 1)
, ("two", 2)
, ("three", 3)
, ("four", 4)
, ("five", 5)
, ("six", 6)
, ("seven", 7)
, ("eight", 8)
2023-12-12 20:25:25 -08:00
, ("nine", 9)]
2023-12-01 22:41:12 -08:00
fullWordMap :: [(String, Int)]
2023-12-12 20:25:25 -08:00
fullWordMap = wordMap ++ (zip =<< map show) [1 .. 9]
2023-12-01 22:41:12 -08:00
opLineBasic :: LineOp
2023-12-12 20:25:25 -08:00
opLineBasic l =
(combineDigits `on` ($ digitToInt <$> filter isDigit l)) head last
2023-12-01 22:41:12 -08:00
firstNumInLine :: String -> [(String, Int)] -> Int
firstNumInLine l = fst . minimumBy (compare `on` snd) . mapMaybe numIndex
where
2023-12-12 20:25:25 -08:00
numIndex (str, num) = (num, ) <$> findIndex (isPrefixOf str) (tails l)
2023-12-01 22:41:12 -08:00
opLineAdvanced :: LineOp
opLineAdvanced l = (combineDigits `on` uncurry firstNumInLine)
2023-12-02 20:30:03 -08:00
<*> bimap reverse (map $ first reverse)
$ (l, fullWordMap)
2023-12-01 22:41:12 -08:00
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