diff options
author | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-19 23:11:52 +0100 |
---|---|---|
committer | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-19 23:12:54 +0100 |
commit | 9064ac2e42e96824b8897e757d3f163cf5f5bc27 (patch) | |
tree | b6f400062f0e1a0965e52fc3eecb31879e22374c | |
parent | bbcd54072a05af59ff160e4ee58d583654906f7e (diff) | |
download | aoc2024-9064ac2e42e96824b8897e757d3f163cf5f5bc27.tar.gz aoc2024-9064ac2e42e96824b8897e757d3f163cf5f5bc27.zip |
19-1: this should be faster but
still doesn't go fast enough but it's too late to debug now. byeee
-rw-r--r-- | 19-1.hs | 31 |
1 files changed, 18 insertions, 13 deletions
@@ -1,12 +1,12 @@ -import Control.Monad.Trans.State +import Control.Monad.ST import Data.Foldable (foldrM) -import Data.HashMap.Lazy as HM hiding (filter, mapMaybe, map, null) +import Data.HashTable.ST.Basic as H import Data.List (nub) import Data.Maybe (mapMaybe) import Debug.Trace -type S = HashMap String [String] +type S s = H.HashTable s String [String] -- Return Nothing if no match; unmatched remainder (can be []) if -- match. @@ -16,20 +16,20 @@ 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 +matchAny :: S s -> [String] -> String -> ST s [String] +matchAny s yss xs = do + t <- H.lookup s xs + case t of Nothing -> let r = mapMaybe (match xs) yss - in put (HM.insert xs r s) >> return r + in H.insert s xs r >> return r Just x -> return x -check :: [String] -> String -> State S Bool -check yss xs = do - zss <- nub <$> matchAny yss xs +check :: S s -> [String] -> String -> ST s Bool +check s yss xs = do + zss <- nub <$> matchAny s yss xs if [] `elem` zss then return True - else anyM (check yss) zss + else anyM (check s yss) zss anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool anyM p = foldrM f False @@ -44,8 +44,13 @@ parse s = let yss = filter (not . null) . drop 2 $ lines s xss = parseTowels . head $ lines s in (xss, yss) +run :: [String] -> [String] -> ST s Int +run xss yss = do + ht <- H.new :: ST s (S s) + length . filter id <$> traverse (check ht yss) xss + main :: IO () main = do input <- getContents let (xss, yss) = parse input - print . length . filter id $ evalState (mapM (check xss) yss) HM.empty + print $ runST $ run yss xss |