Add solution for 2010 day 16
[?]
Jun 24, 2021, 2:37 AM
RF5UJPAID7B3EYSZBOYQW6D7OXRX6OAL5V3H2IQIWNXS4ZDVBBUACDependencies
- [2]
B527MN66Solve day 1 for 2020
Change contents
- file addition: day16.hs[2.17]
{-# LANGUAGE MultiWayIf #-}import Codec.Phaserimport Codec.Phaser.Commonimport Codec.Phaser.Core (eof)import Codec.Phaser.UTF8import Control.Applicativeimport Data.Charimport Data.Functor.Composeimport Data.Foldableimport Data.Listimport qualified Data.Map as Mimport qualified Data.Sequence as Simport System.Environmentnewtype Predicate a = Predicate { getPredicate :: a -> Bool }instance Semigroup (Predicate a) wherePredicate a <> Predicate b = Predicate (\x -> a x || b x)instance Monoid (Predicate a) wheremempty = Predicate (const False)validity :: Monoid p => Phase p Char o (M.Map String (Integer -> Bool))validity = mconcat <$> sepBy (M.singleton <$>munch (/= ':') <*>(char ':' *> munch isSpace *> (getPredicate . foldMap Predicate <$> sepBy((\a b t -> t >= a && t <= b) <$> positiveIntegerDecimal <*>(char '-' *> positiveIntegerDecimal))(munch isSpace *> string "or" *> munch isSpace)))) (char '\n')ticket :: Monoid p => Phase p Char o (S.Seq Integer)ticket = S.fromList <$> sepBy positiveIntegerDecimal (char ',')data Input = Input {ranges :: M.Map String (Integer -> Bool),myTicket :: S.Seq Integer,nearbyTickets :: [S.Seq Integer]}input :: Monoid p => Phase p Char o Inputinput = Input <$>validity <*>(munch isSpace *> string "your ticket:" *> munch isSpace *> ticket) <*>(munch isSpace *> string "nearby tickets:" *> munch isSpace *> sepBy ticket (char '\n') <* (() <$ char '\n' <|> eof))errorRate :: Input -> IntegererrorRate s = lett = not . getPredicate (foldMap Predicate $ ranges s)in sum $ Compose $ map (S.filter t) $ nearbyTickets sonlyValid :: Input -> InputonlyValid s = lett = getPredicate (foldMap Predicate $ ranges s)in s {nearbyTickets = filter ((&&) <$> (not . S.null) <*> all t) $ nearbyTickets s}columns :: Input -> [M.Map String Int]columns s = letunknown = M.keys (ranges s) <$ myTicket sreduced = foldl' (S.zipWith $ \c v ->filter (\c' -> case M.lookup c' (ranges s) ofNothing -> FalseJust f -> f v) c) unknown $ nearbyTickets ssolve :: S.Seq [String] -> [S.Seq [String]]solve s = letknown = do[c] <- foldMap (:[]) sreturn cin if| known /= nub known -> []| length known == S.length s -> [s]| otherwise -> lets1 :: S.Seq [String]s1 = fmap (\c -> case c of[_] -> c_ -> filter (not . flip elem known) c) sin if s1 == sthen letnarrowest = foldr (\c r n -> case c of[_] -> r (n + 1)_ -> case r (n + 1) ofJust (n', c')| length c' < length c -> Just (n', c')_ -> Just (n, c)) (const Nothing) s1 0in case narrowest ofNothing -> solve s1Just (i, c) -> c >>= \c' -> solve $ S.update i [c'] s1else solve s1in map (fold . S.mapWithIndex (\i [c] -> M.singleton c i)) $ solve reduceddepartureFields :: M.Map String Int -> S.Seq Integer -> M.Map String IntegerdepartureFields cols tk = M.fromList $ do(k,i) <- M.toList colsif "departure" `isPrefixOf` kthen [()]else []Just v <- [S.lookup i tk]return (k,v)main = do[fn] <- getArgsparseResult <- parseFile (utf8_stream >># trackPosition >># input) fncase parseResult ofRight (s:_) -> doputStrLn $ "Part 1: " ++ show (errorRate s)lets1 = onlyValid scols = head $ columns s1putStrLn $ "Part 2: " ++ show (product $ departureFields cols $ myTicket s1)Left e -> print e