1 {-# LANGUAGE NegativeLiterals #-}
2 {-# LANGUAGE OverloadedStrings #-}
4 import Data.Text (Text)
5 import qualified Data.Text.IO as TIO
7 import Data.Void (Void)
10 import Text.Megaparsec.Char
11 import qualified Text.Megaparsec.Char.Lexer as L
12 import qualified Control.Applicative as CA
14 import Data.IntSet (IntSet)
15 import qualified Data.IntSet as S
19 text <- TIO.readFile "data/advent01.txt"
20 let changes = successfulParse text
29 part2 = snd . head . dropWhile unRepeated . scanl merge (S.empty, 0) . cycle
31 merge :: (IntSet, Int) -> Int -> (IntSet, Int)
32 merge (frequencies, frequency) change = (S.insert frequency frequencies, frequency + change)
34 unRepeated :: (IntSet, Int) -> Bool
35 unRepeated (frequencies, frequency) = frequency `S.notMember` frequencies
37 -- Parse the input file
38 type Parser = Parsec Void Text
41 sc = L.space (skipSome spaceChar) CA.empty CA.empty
42 -- sc = L.space (skipSome (char ' ')) CA.empty CA.empty
46 integer = lexeme L.decimal
47 signedInteger = L.signed sc integer
49 changesP = many signedInteger
51 successfulParse :: Text -> [Int]
52 successfulParse input =
53 case parse changesP "input" input of
54 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
55 Right changes -> changes