1 import qualified Data.Map.Strict as M
2 import Text.ParserCombinators.ReadP
3 import Control.Applicative ((<|>))
7 shifts <- map parse . lines <$> getContents
12 data Status = Begin | Awake | Asleep deriving (Show)
13 data Date = Date Int Int Int deriving (Show)
14 data Time = Time Int Int deriving (Show)
16 data Shift = Shift Status GID Date Time deriving (Show)
18 parse :: String -> Shift
19 parse = fst . head . readP_to_S go
20 where digit :: ReadP Char
21 digit = satisfy (\char -> char >= '0' && char <= '9')
22 stGet :: String -> Status
23 stGet "wakes up" = Awake
24 stGet "falls asleep" = Asleep
25 stGet "Guard #" = Begin
29 year <- read <$> count 4 digit
31 month <- read <$> count 2 digit
33 day <- read <$> count 2 digit
35 hour <- read <$> count 2 digit
37 minute <- read <$> count 2 digit
39 rt <- string "Guard #" <|> string "wakes up" <|> string "falls asleep"
40 gid <- option (-1) (read <$> many1 digit)
41 optional $ string " begins shift"
43 let d = Date year month day
44 let t = Time hour minute
45 return (Shift (stGet rt) gid d t)