3b7a71c50a68713884cfb3468b92353389d68b3f
[advent-of-code-18.git] / src / advent01 / advent01.hs
1 {-# LANGUAGE NegativeLiterals #-}
2 {-# LANGUAGE OverloadedStrings #-}
3
4 import Data.Text (Text)
5 import qualified Data.Text.IO as TIO
6
7 import Data.Void (Void)
8
9 import Text.Megaparsec
10 import Text.Megaparsec.Char
11 import qualified Text.Megaparsec.Char.Lexer as L
12 import qualified Control.Applicative as CA
13
14 import Data.IntSet (IntSet)
15 import qualified Data.IntSet as IntSet
16
17 main :: IO ()
18 main = do
19 text <- TIO.readFile "data/advent01.txt"
20 let changes = successfulParse text
21 print $ part1 changes
22 print $ part2 changes
23
24
25 part1 :: [Int] -> Int
26 part1 = sum
27
28 part2 :: [Int] -> Int
29 part2 changes = snd $ head $ dropWhile unRepeated $ scanl merge (IntSet.empty, 0) $ cycle changes
30
31
32 merge :: (IntSet, Int) -> Int -> (IntSet, Int)
33 merge (s, f) c = (IntSet.insert f s, f+c)
34
35 unRepeated :: (IntSet, Int) -> Bool
36 unRepeated (s, f) = f `IntSet.notMember` s
37
38 -- Parse the input file
39 type Parser = Parsec Void Text
40
41 sc :: Parser ()
42 -- sc = L.space (skipSome spaceChar) CA.empty CA.empty
43 sc = L.space (skipSome (char ' ')) CA.empty CA.empty
44
45
46 lexeme = L.lexeme sc
47 integer = lexeme L.decimal
48 signedInteger = L.signed sc integer
49
50 -- symb = L.symbol sc
51 -- comma = symb ","
52
53
54 changesP = signedInteger `sepEndBy` newline
55
56
57 successfulParse :: Text -> [Int]
58 successfulParse input =
59 case parse changesP "input" input of
60 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
61 Right changes -> changes