Broke days into individual pacakges
[advent-of-code-16.git] / adventofcode1609 / app / advent09.hs
1 module Main(main) where
2
3 import Data.List.Split (splitOn)
4 import Data.Char (isSpace)
5
6 type Chunk = (Int, String)
7
8 main :: IO ()
9 main = do
10 textL <- readFile "data/advent09.txt"
11 let text = filter (not . isSpace) textL
12 part1 text
13 part2 text
14
15 part1 :: String -> IO ()
16 part1 text = do
17 print $ cLength $ decompress text
18
19 part2 :: String -> IO ()
20 part2 text = do
21 print $ cLength $ decompress2 text
22
23
24 decompress :: String -> [Chunk]
25 decompress text =
26 if not (null msuf)
27 then (1, pre):(num, chunk):drest
28 else [(1, pre)]
29 where
30 (pre, msuf) = span ('(' /= ) text
31 (marker, suf) = span (')' /= ) msuf
32 ln = splitOn "x" (tail marker)
33 len = read (ln!!0) :: Int
34 num = read (ln!!1) :: Int
35 (chunk, remainder) = splitAt len (tail suf)
36 drest = decompress remainder
37
38 decompress2 :: String -> [Chunk]
39 decompress2 text =
40 if not (null msuf)
41 then [(1, pre)] ++ mulDchunks ++ drest
42 else [(1, pre)]
43 where
44 (pre, msuf) = span ('(' /= ) text
45 (marker, suf) = span (')' /= ) msuf
46 ln = splitOn "x" (tail marker)
47 len = read (ln!!0) :: Int
48 num = read (ln!!1) :: Int
49 (chunk, remainder) = splitAt len (tail suf)
50 dchunks = decompress2 chunk
51 mulDchunks = [(dl * num, ds) | (dl, ds) <- dchunks]
52 drest = decompress2 remainder
53
54 cLength :: [Chunk] -> Int
55 cLength = sum . map (clen)
56 where clen (n, t) = n * (length t)
57