import Text.Parsec.String (Parser) import Text.Parsec import System.Environment import Data.List import Data.Function import Data.Maybe import qualified Data.Map as M import Control.Monad data Color = Red | Green | Blue deriving (Show,Eq,Ord) type Handful = (Color, Int) type Set = M.Map Color Int type Game = (Int, [Set]) red = string "red" *> pure Red green = string "green" *> pure Green blue = string "blue" *> pure Blue color :: Parser Color color = red <|> green <|> blue handful :: Parser Handful handful = liftM2 (flip (,)) (space *> (read <$> many1 digit)) (space *> color) set = M.fromList <$> (sepBy handful $ string ",") game = liftM2 (,) (string "Game " *> (read <$> many1 digit)) (string ":" *> sepBy set (string ";")) games = sepBy game newline solution :: Game -> Int solution = product . M.elems . M.unionsWith max . snd main = head <$> getArgs >>= \a -> do r <- readFile a print $ sum $ map solution $ either (error.show) id $ parse games a r