diff options
author | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-19 22:50:30 +0100 |
---|---|---|
committer | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-19 22:50:30 +0100 |
commit | bbcd54072a05af59ff160e4ee58d583654906f7e (patch) | |
tree | c0cee1e4e2a7774edfbde9cb2f1b59ba87f5e57c | |
parent | 81baad10d0bc2344548c10affba4a8896bf6f685 (diff) | |
download | aoc2024-bbcd54072a05af59ff160e4ee58d583654906f7e.tar.gz aoc2024-bbcd54072a05af59ff160e4ee58d583654906f7e.zip |
19-1: "working" but too slow.
-rw-r--r-- | 19-1.hs | 51 |
1 files changed, 51 insertions, 0 deletions
@@ -0,0 +1,51 @@ +import Control.Monad.Trans.State +import Data.Foldable (foldrM) +import Data.HashMap.Lazy as HM hiding (filter, mapMaybe, map, null) +import Data.List (nub) +import Data.Maybe (mapMaybe) + +import Debug.Trace + +type S = HashMap String [String] + +-- Return Nothing if no match; unmatched remainder (can be []) if +-- match. +match :: String -> String -> Maybe String +match xs [] = Just xs +match (x:xs) (y:ys) | x == y = match xs ys + | otherwise = Nothing +match [] _ = Nothing + +matchAny :: [String] -> String -> State S [String] +matchAny yss xs = do + s <- get + case HM.lookup xs s of + Nothing -> let r = mapMaybe (match xs) yss + in put (HM.insert xs r s) >> return r + Just x -> return x + +check :: [String] -> String -> State S Bool +check yss xs = do + zss <- nub <$> matchAny yss xs + if [] `elem` zss + then return True + else anyM (check yss) zss + +anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool +anyM p = foldrM f False + where + f a b = (b ||) <$> p a + +parseTowels :: String -> [String] +parseTowels = map init . words + +parse :: String -> ([String],[String]) +parse s = let yss = filter (not . null) . drop 2 $ lines s + xss = parseTowels . head $ lines s + in (xss, yss) + +main :: IO () +main = do + input <- getContents + let (xss, yss) = parse input + print . length . filter id $ evalState (mapM (check xss) yss) HM.empty |