Add day 2 solution
[?]
Dec 14, 2020, 10:52 PM
EF5QJNSQEJWTSTVHBZRDIAXHN5IK2RXV2OEUWYORDJXMI7RSLXOACDependencies
- [2]
B527MN66Solve day 1 for 2020
Change contents
- file addition: day2.hs[2.17]
{-# LANGUAGE RankNTypes #-}import Control.Applicativeimport Control.Monadimport Control.Monad.Failimport Data.Charimport System.Environmentimport System.IOdata C a = R a | F | C (Char -> C a) | B (C a) (C a)newtype P a = P { getP :: forall b . (a -> C b) -> C b }instance Functor P wherefmap f (P c) = P (c . (. f))instance Applicative P wherepure a = P ($ a)P f <*> P a = P (f . (a . ) . (.))P a *> P b = P (a . const . b)P a <* P b = P (a . ((b . const) .))instance Monad P whereP a >>= f = P (a . flip (getP . f))instance MonadFail P wherefail _ = emptyinstance Alternative P whereempty = P (const F)P a <|> P b = P (\c -> reduce $ B (a c) (b c))instance MonadPlus P wheremzero = emptymplus = (<|>)reduce (B F b) = breduce (B a F) = areduce (B (C a) (C b)) = C (\i -> reduce $ B (a i) (b i))reduce c = crunP :: P a -> String -> [a]runP p i = extract $ go (getP p R) i whereextract (R r) = [r]extract (B a b) = extract a ++ extract bextract _ = []go p [] = pgo F _ = Fgo p (a:r) = go (step p a) rstep :: C a -> Char -> C astep (C p) a = p astep (B a b) i = reduce (B (step a i) (step b i))step _ _ = FgetC :: P ChargetC = P Cpeek :: P Charpeek = P (\c -> C (\i -> step (c i) i))replace :: Char -> P ()replace i = P (\c -> step (c ()) i)eos :: P ()eos = P (\c -> strip (c ())) wherestrip r@(R _) = rstrip F = Fstrip (C p) = Fstrip (B a b) = reduce (B (strip a) (strip b))satisfy :: (Char -> Bool) -> P Charsatisfy p = getC >>= \c -> if p cthen return celse emptymunch :: (Char -> Bool) -> P Stringmunch p = go id wherego acc = letr = acc []in (getC >>= \c -> if p cthen go (acc . (c:))else r <$ replace c) <|> (r <$ eos)char :: Char -> P Charchar c = satisfy (== c)number :: (Num n) => P nnumber = go 0 wherego t = dod <- (fromIntegral . digitToInt) <$> satisfy isDigitlet t' = t * 10 + dgo t' <|> return (fromInteger t')countWithSep :: P Bool -> P s -> P IntegercountWithSep i s = letgo n = n `seq` i >>= \i' -> letn' = if i' then n + 1 else nin (s *> go n') <|> return n'in go 0 <|> return 0range :: P (Integer,Integer)range = (,) <$> number <*> (char '-' *> number)line :: Int -> P Boolline v = do~(lo,hi) <- rangemunch isSpacec <- getCchar ':'munch isSpacecase v of1 -> fmap ((&&) <$> (>= lo) <*> (<= hi)) $countWithSep (fmap (==c) $ satisfy (not . isSpace)) (return ())2 -> (==1) <$> cpp c 0 [lo,hi] 1wherecpp _ n [] _ = n <$ munch (not . isSpace)cpp x n l@(c:r) p| c == p = getC >>= \x' -> letn' = if x' == xthen n + 1else nin cpp x n' r (p + 1)| otherwise = getC *> cpp x n l (p + 1)problemFile :: Int -> P IntegerproblemFile v = countWithSep (line v) (char '\n') <* (return () <|> (() <$ char '\n'))example :: Stringexample = "1-3 a: abcde\n1-3 b: cdefg\n2-9 c: ccccccccc"main = do~[fn,v] <- getArgsf <- readFile fnlet (r:_) = runP (problemFile $ read v) fprint r