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