Day 5
[advent-of-code-18.git] / src / advent05 / advent05.hs
1 import Data.List
2 import Data.Char (toLower)
3
4 main :: IO ()
5 main = do
6 text <- readFile "data/advent05.txt"
7 -- let ids = lines text
8 print $ part1 text
9 print $ part2 text
10 -- putStrLn $ part2 ids
11
12
13 part1 = reactedLength
14
15 part2 polymer = minimum finalLengths
16 where finalLengths = map (\u -> reactedLength $ removeUnit polymer u) units
17 units = unitsPresent polymer
18
19
20 react :: String -> Char -> Char -> String -> (String, String)
21 react prefix a b suffix =
22 if willReact a b
23 then (prefix, suffix)
24 else ((b:a:prefix), suffix)
25
26 willReact :: Char -> Char -> Bool
27 willReact a b = (a /= b) && (toLower a == toLower b)
28
29
30 reactHere :: (String, String) -> Maybe ((String, String), (String, String))
31 reactHere (prefix, suffix) =
32 if canContinue prefix suffix
33 then Just ((prefix'', suffix''), (prefix'', suffix''))
34 else Nothing
35 where (prefix', a, b, suffix') = reactionSite prefix suffix
36 (prefix'', suffix'') = react prefix' a b suffix'
37
38
39 canContinue (_:_) (_:_) = True
40 canContinue [] (_:_:_) = True
41 canContinue _ _ = False
42
43 reactionSite (a:prefix) (b:suffix) = (prefix, a, b, suffix)
44 reactionSite [] (a:b:suffix) = ([], a, b, suffix)
45
46
47 reactedLength polymer = length prefix + length suffix
48 where (prefix, suffix) = last $ unfoldr reactHere ("", polymer)
49
50
51 unitsPresent = nub . sort . map toLower
52
53 removeUnit polymer unit = filter (\c -> toLower c /= unit ) polymer