{-# Language QuasiQuotes #-}
module Main (main) where
import Advent (fromDigits, format)
import Text.ParserCombinators.ReadP (readP_to_S, string, (<++), choice, get)
main :: IO ()
IO ()
main =
do [[Char]]
input <- [format|2023 1 (%s%n)*|]
Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (([Char] -> Int) -> [[Char]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map ([([Char], Int)] -> [Char] -> Int
decode [([Char], Int)]
part1) [[Char]]
input))
Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (([Char] -> Int) -> [[Char]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map ([([Char], Int)] -> [Char] -> Int
decode [([Char], Int)]
part2) [[Char]]
input))
part1, part2 :: [(String, Int)]
part1 :: [([Char], Int)]
part1 = [(Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i, Int
i) | Int
i <- [Int
0..Int
9]]
part2 :: [([Char], Int)]
part2 = [([Char], Int)]
part1 [([Char], Int)] -> [([Char], Int)] -> [([Char], Int)]
forall a. [a] -> [a] -> [a]
++
[([Char]
"one" ,Int
1),([Char]
"two" ,Int
2),([Char]
"three",Int
3),
([Char]
"four" ,Int
4),([Char]
"five" ,Int
5),([Char]
"six" ,Int
6),
([Char]
"seven",Int
7),([Char]
"eight",Int
8),([Char]
"nine" ,Int
9)]
earliest :: [(String, a)] -> String -> a
earliest :: forall a. [([Char], a)] -> [Char] -> a
earliest [([Char], a)]
mapping [Char]
str =
case ReadP a -> ReadS a
forall a. ReadP a -> ReadS a
readP_to_S ReadP a
p [Char]
str of
(a, [Char])
x:[(a, [Char])]
_ -> (a, [Char]) -> a
forall a b. (a, b) -> a
fst (a, [Char])
x
[] -> [Char] -> a
forall a. HasCallStack => [Char] -> a
error ([Char]
"no match for: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
str)
where
p :: ReadP a
p = [ReadP a] -> ReadP a
forall a. [ReadP a] -> ReadP a
choice [a
v a -> ReadP [Char] -> ReadP a
forall a b. a -> ReadP b -> ReadP a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ [Char] -> ReadP [Char]
string [Char]
k | ([Char]
k,a
v) <- [([Char], a)]
mapping] ReadP a -> ReadP a -> ReadP a
forall a. ReadP a -> ReadP a -> ReadP a
<++ (ReadP Char
get ReadP Char -> ReadP a -> ReadP a
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ReadP a
p)
decode :: [(String, Int)] -> String -> Int
decode :: [([Char], Int)] -> [Char] -> Int
decode [([Char], Int)]
mapping [Char]
str = Int -> [Int] -> Int
forall a. (HasCallStack, Integral a) => a -> [a] -> a
fromDigits Int
10 [Int
d1,Int
d2]
where
d1 :: Int
d1 = [([Char], Int)] -> [Char] -> Int
forall a. [([Char], a)] -> [Char] -> a
earliest [([Char], Int)]
mapping [Char]
str
d2 :: Int
d2 = [([Char], Int)] -> [Char] -> Int
forall a. [([Char], a)] -> [Char] -> a
earliest [([Char] -> [Char]
forall a. [a] -> [a]
reverse [Char]
k, Int
v) | ([Char]
k,Int
v) <- [([Char], Int)]
mapping] ([Char] -> [Char]
forall a. [a] -> [a]
reverse [Char]
str)