import Control.Arrow import Control.Monad import Data.List main :: IO () main = interact $ show . day12 . map parse . lines parse :: String -> (String, [Int]) parse = second (read . ('[' :) . (++ "]") . tail) . break (== ' ') day12 :: [(String, [Int])] -> Int day12 = sum . map (length . genArrangements) part2ify :: (String, [Int]) -> (String, [Int]) part2ify (s, xs) = (intercalate "?" $ replicate 5 s, concat $ replicate 5 xs) genMin :: [Int] -> [String] genMin = foldr (\x -> (:) (replicate x '#' ++ ".")) [] genDots :: Int -> Int -> [[Int]] genDots n x = filter (\xs -> sum xs == x) $ replicateM n [0 .. x] buildMaxeds :: [String] -> [[Int]] -> [String] buildMaxeds ss = map (build ss) build :: [String] -> [Int] -> String build [] [x] = replicate x '.' build (s:ss) (x:xs) = replicate x '.' ++ s ++ build ss xs genArrangements :: (String, [Int]) -> [String] genArrangements (s, xs) = filter f $ buildMaxeds (genMin xs) (genDots w l) where f x = and (zipWith wEq s x) w = succ $ length xs l = length s - sum xs - pred (length xs) wEq :: Char -> Char -> Bool wEq _ '?' = True wEq '?' _ = True wEq c1 c2 = c1 == c2