/
Day1.hs
48 lines (42 loc) · 1.45 KB
/
Day1.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
module Main where
import Data.List (sortOn)
import Data.Ord (Down(..))
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Read as T
import System.Environment (getArgs)
import System.Exit (exitFailure)
import System.IO (hPutStrLn, stderr)
toValues :: Text -> Either String [[Int]]
toValues = fmap groupMaybes . traverse toNum . T.lines
where
toNum :: Text -> Either String (Maybe Int)
toNum txt
| T.null txt = Right Nothing
| otherwise = case T.decimal txt of
Left t -> Left t
Right (i, remainder)
| T.null remainder -> Right (Just i)
| otherwise -> Left "Parse error!"
groupMaybes :: [Maybe Int] -> [[Int]]
groupMaybes = go id
where
go :: ([Int] -> [Int]) -> [Maybe Int] -> [[Int]]
go f [] = [f []]
go f (Nothing:xs) = f [] : go id xs
go f (Just i:xs) = go (f . (i:)) xs
main :: IO ()
main = do
args <- getArgs
inputData <- case args of
[inputFile] -> T.readFile inputFile
_ -> hPutStrLn stderr "No input file!" >> exitFailure
case toValues inputData of
Left err -> putStrLn $ "Error reading input: " <> err
Right v -> do
let calorieCounts = map sum v
putStr $ "Puzzle #1: "
print $ maximum calorieCounts
putStr $ "Puzzle #2: "
print . sum . take 3 $ sortOn Down calorieCounts