From 5a89816e03831e8b905d8f8fa2bd44c6decdfb7a Mon Sep 17 00:00:00 2001 From: Joscha Date: Wed, 16 Dec 2020 16:51:32 +0000 Subject: [PATCH] [hs] Solve 2020_16 part 1 --- hs/src/Aoc/Y2020.hs | 2 ++ hs/src/Aoc/Y2020/D16.hs | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 hs/src/Aoc/Y2020/D16.hs diff --git a/hs/src/Aoc/Y2020.hs b/hs/src/Aoc/Y2020.hs index 975d004..2e29ab8 100644 --- a/hs/src/Aoc/Y2020.hs +++ b/hs/src/Aoc/Y2020.hs @@ -18,6 +18,7 @@ import qualified Aoc.Y2020.D12 as D12 import qualified Aoc.Y2020.D13 as D13 import qualified Aoc.Y2020.D14 as D14 import qualified Aoc.Y2020.D15 as D15 +import qualified Aoc.Y2020.D16 as D16 year :: Year year = Year 2020 @@ -36,4 +37,5 @@ year = Year 2020 , (13, D13.day) , (14, D14.day) , (15, D15.day) + , (16, D16.day) ] diff --git a/hs/src/Aoc/Y2020/D16.hs b/hs/src/Aoc/Y2020/D16.hs new file mode 100644 index 0000000..30132b4 --- /dev/null +++ b/hs/src/Aoc/Y2020/D16.hs @@ -0,0 +1,52 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Aoc.Y2020.D16 + ( day + ) where + +import Control.Monad + +import qualified Data.Map as Map +import qualified Data.Text as T + +import Aoc.Day +import Aoc.Parse + +data Input = Input + { iFields :: Map.Map T.Text [(Int, Int)] + , iMyTicket :: [Int] + , iNearbyTickets :: [[Int]] + } deriving (Show) + +parser :: Parser Input +parser = do + fields <- Map.fromList <$> many (fieldLine <* newline) + void $ string "\nyour ticket:\n" + myTicket <- ticket <* newline + void $ string "\nnearby tickets:\n" + nearbyTickets <- many (ticket <* newline) + pure $ Input fields myTicket nearbyTickets + where + fieldLine = do + name <- takeWhileP Nothing $ \c -> (c /= ':') && (c /= '\n') + void $ string ": " + ranges <- sepBy ((,) <$> (decimal <* string "-") <*> decimal) (string " or ") + pure (name, ranges) + ticket = decimal `sepBy` string "," + +valid :: Int -> [(Int, Int)] -> Bool +valid n = any (\(a, b) -> a <= n && n <= b) + +findValid :: Map.Map T.Text [(Int, Int)] -> Int -> [T.Text] +findValid fields n = map fst $ filter (valid n . snd) $ Map.toList fields + +anyValid :: Map.Map T.Text [(Int, Int)] -> Int -> Bool +anyValid fields = not . null . findValid fields + +solver :: Input -> IO () +solver i = do + putStrLn ">> Part 1" + print $ sum $ filter (not . anyValid (iFields i)) $ concat $ iNearbyTickets i + +day :: Day +day = dayParse parser solver