import Data.List.Split (splitOn) import Data.List (group) matchesConsecutive :: [Int] -> String -> Bool matchesConsecutive xs = (==) xs . map length . filter ((==) '#' . head) . group allSprings :: String -> [String] allSprings "" = [""] allSprings (x:xs) = allSprings xs >>= (\s -> map (:s) possibleChars) where possibleChars = if x == '?' then ['.', '#'] else [x] solve :: (String, [Int]) -> Int solve (springs, records) = length . filter (matchesConsecutive records) . allSprings $ springs parseLine :: String -> (String, [Int]) parseLine l = (x, map read . splitOn "," $ y) where (x:y:_) = splitOn " " l main :: IO () main = print . sum . map (solve . parseLine) . filter (not . null) . lines =<< readFile "data.txt"