-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.hs
51 lines (43 loc) · 1.27 KB
/
run.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
num :: Parsec Void String Int
num = read <$> some digitChar
marker :: Parsec Void String (Int, Int)
marker = between (char '(')
(char ')')
((,) <$> (num <* char 'x') <*> num)
markerLength :: (Int, Int) -> Int
markerLength (x, y) = length (show x ++ show y) + 3
decompressedLength :: String -> Int -> Int
decompressedLength [] acc = acc
decompressedLength s@(_:rest) acc =
case parse marker "" s of
Right (len, times) ->
let mlen = markerLength (len, times)
next = drop (len + mlen) s
in
decompressedLength next (acc + len * times)
Left _ ->
decompressedLength rest (acc + 1)
part1 :: String -> Int
part1 = flip decompressedLength 0
decl2 :: String -> Integer
decl2 [] = 0
decl2 s =
case parse marker "" s of
Right (len, times) ->
let mlen = markerLength (len, times)
noMarker = drop mlen s
marked = take len noMarker
in
(fromIntegral times * decl2 marked) + decl2 (drop len noMarker)
Left _ ->
1 + decl2 (drop 1 s)
part2 :: String -> Integer
part2 = decl2
main :: IO ()
main = do
input <- filter (/= '\n') <$> readFile "input.txt"
print (part1 input)
print (part2 input)