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