import Data.List.Split (splitOn) game :: String -> [String] game = splitOn [';'] reveal :: String -> [String] reveal x = concat ( map (splitOn [',']) (game x) ) colors :: String -> [(Int, String)] colors x = map (\x -> color (splitOn [' '] x)) (reveal x) color :: [String] -> (Int, String) color [_, i, s] = (read i, s) validColor :: (Int, String) -> Bool validColor (i, s) = case s of "red" -> i <= 12 "green" -> i <= 13 "blue" -> i <= 14 _ -> False getColors :: String -> String getColors s = tail (dropWhile (/= ':') s) isGameValid :: String -> Bool isGameValid s = all validColor (colors (getColors s)) isValid :: [String] -> Bool isValid s = all isGameValid s getMyColor :: String -> [(Int, String)] getMyColor s = colors (getColors s) myFilter :: String -> [(Int, String)] -> Int myFilter color s = maximum (map (\(i,_) -> i) (filter (\(_,c) -> c == color) s)) main :: IO () main = do inputLines <- lines <$> getContents -- let arePossible = filter isPossible lines -- myColors <- isValid inputLines -- print (sum (map (\(_,n) -> n) (filter (\(b,_) -> b) (zip (map isGameValid inputLines) [1..])))) let myColors = map (\x -> getMyColor x) inputLines let myResult = map (\c -> myFilter "red" c * myFilter "green" c * myFilter "blue" c) myColors print (sum myResult) -- mapM_ putStrLn myColors -- mapM_ putStrLn inputLines