55 lines
1.7 KiB
Haskell
55 lines
1.7 KiB
Haskell
import Debug.Trace
|
|
import Text.Regex
|
|
import Data.List
|
|
import qualified Data.List.Split as S
|
|
|
|
import Data.Function.Memoize
|
|
import Control.Parallel.Strategies
|
|
|
|
traceOut :: Show a => a -> a
|
|
traceOut x = (traceShow x x)
|
|
|
|
addFirst :: [[a]] -> a -> [[a]]
|
|
addFirst [] x = [[x]]
|
|
addFirst (y:ys) x = ([x] ++ y) : ys
|
|
|
|
split :: [Char] -> String -> [String]
|
|
split _ [] = []
|
|
split delims (x:xs)
|
|
| elem x delims = [[]] ++ split delims xs
|
|
| otherwise = addFirst (split delims xs) x
|
|
|
|
splitInput :: String -> [String]
|
|
splitInput = filter (/="") . split ", "
|
|
|
|
splitInput2 :: String -> [String]
|
|
splitInput2 = split "\n"
|
|
|
|
solve1 :: [String] -> [String] -> Int
|
|
solve1 patterns towels = length $ filter (match (mkRegex ("^(" ++ (concat $ intersperse "|" patterns) ++ ")*$"))) towels
|
|
|
|
match :: Regex -> String -> Bool
|
|
match regex str = case matchRegex regex str of
|
|
Just _ -> True
|
|
Nothing -> False
|
|
|
|
solveTowel :: [String] -> String -> Int
|
|
solveTowel patterns towel = sum $ ((map (
|
|
\pattern -> case matchRegexAll (mkRegex ('^':pattern)) towel of
|
|
Nothing -> 0
|
|
Just (_, _, remaining, _) -> if remaining == "" then 1 else (memoize2 solveTowel) patterns remaining
|
|
) patterns) `using` parList rdeepseq)
|
|
|
|
solve2 :: [String] -> [String] -> Int
|
|
solve2 patterns towels = sum $ ((map ((memoize2 solveTowel) patterns) towels) `using` parList rdeepseq)
|
|
|
|
main :: IO()
|
|
main = do
|
|
fileinp <- readFile "input.txt"
|
|
let sections = S.splitOn "\n\n" fileinp
|
|
let parsed = splitInput (sections!!0)
|
|
let parsed2 = splitInput2 (sections!!1)
|
|
let solved1 = solve1 parsed parsed2
|
|
let solved2 = solve2 parsed parsed2
|
|
print solved1
|
|
print solved2
|