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