never executed always true always false
1 {-|
2 Module: Y2016.D01
3 Description: Advent of Code Day 01 Solutions.
4 License: MIT
5 Maintainer: @tylerjl
6
7 Solutions to the day 01 set of problems for <adventofcode.com>.
8 -}
9 module Y2018.D01
10 ( frequency
11 , twiceFrequency
12 ) where
13
14 import Y2015.Util (regularParse, intParser)
15
16 import Control.Applicative ((<|>))
17 import Data.List (foldl')
18 import Text.Parsec.String (Parser)
19 import Text.Parsec.Char (endOfLine)
20 import Text.Parsec
21 ( ParseError
22 , many
23 , optional
24 , string
25 , try)
26
27 data Change = Increase Int
28 | Decrease Int
29 deriving Eq
30
31 parseFrequency :: String
32 -> Either ParseError [Change]
33 parseFrequency = regularParse freqParser
34
35 freqParser :: Parser [Change]
36 freqParser = many (parseChange <* optional endOfLine)
37
38 parseChange :: Parser Change
39 parseChange = try (Increase <$ string "+" <*> intParser)
40 <|> try (Decrease <$ string "-" <*> intParser)
41
42 frequency :: String -> Maybe Int
43 frequency input = case parseFrequency input of
44 Left _ -> Nothing
45 Right f -> Just $ foldl' freqSum 0 f
46
47 freqSum :: Int -> Change -> Int
48 freqSum n (Increase i) = n + i
49 freqSum n (Decrease i) = n - i
50
51 twiceFrequency :: String -> Maybe Int
52 twiceFrequency input = case parseFrequency input of
53 Left _ -> Nothing
54 Right f -> Just $ findRepeatedFrequency (cycle f) [] 0
55
56 findRepeatedFrequency :: [Change] -> [Int] -> Int -> Int
57 findRepeatedFrequency (change:changes) history current =
58 if current' `elem` history then
59 current'
60 else
61 findRepeatedFrequency changes history' current'
62 where history' = history ++ [current]
63 current' = freqSum current change
64 findRepeatedFrequency [] _ current = current