Strict fold
[advent-of-code-16.git] / advent15l.hs
1 import Text.Parsec
2 import Text.ParserCombinators.Parsec.Number
3
4 main :: IO ()
5 main = do
6 text <- readFile "advent15.txt"
7 let disks = successfulParse $ parseIfile text
8 part1 disks
9 part2 disks
10
11 part1 :: [[Int]] -> IO ()
12 part1 disks = print $ head $ filter (canFall disks) [0..]
13
14 part2 :: [[Int]] -> IO ()
15 part2 disks = print $ head $ filter (canFall disks2) [0..]
16 where disks2 = disks ++ [drop 7 $ drop 0 $ cycle [0..(11-1)]]
17
18 canFall :: [[Int]] -> Int -> Bool
19 canFall ds i = all (\d -> (d!!i) == 0) ds
20
21
22 instructionFile = instructionLine `endBy` newline
23 instructionLine = diskify <$> (string "Disc #" *> int)
24 <*> (string " has " *> int)
25 <*> (string " positions; at time=0, it is at position " *> int)
26 <* (string ".")
27 where diskify n size pos0 = drop n $ drop pos0 $ cycle [0..(size-1)]
28
29 parseIfile :: String -> Either ParseError [[Int]]
30 parseIfile input = parse instructionFile "(unknown)" input
31
32 parseIline :: String -> Either ParseError [Int]
33 parseIline input = parse instructionLine "(unknown)" input
34
35 successfulParse :: Either ParseError [a] -> [a]
36 successfulParse (Left _) = []
37 successfulParse (Right a) = a