X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=advent04%2FMain.hs;fp=advent04%2FMain.hs;h=456b157c6af47a8eda8d32d7b6bbace22c1b2540;hb=b8fa5f9013026264b0509f0498f4b897c9b4c824;hp=0000000000000000000000000000000000000000;hpb=e3148f938dcdeeda7da459cf2e153a4a712c2b5f;p=advent-of-code-22.git diff --git a/advent04/Main.hs b/advent04/Main.hs new file mode 100644 index 0000000..456b157 --- /dev/null +++ b/advent04/Main.hs @@ -0,0 +1,66 @@ +-- Writeup at https://work.njae.me.uk/2022/12/04/advent-of-code-2022-day-4/ + +import System.Environment +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (Result) +-- import Control.Applicative + +data Assignment = Assignment Int Int deriving (Show, Eq) +type Pair = (Assignment, Assignment) + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let pairs = successfulParse text + print $ part1 pairs + print $ part2 pairs + +getDataFileName :: IO String +getDataFileName = + do args <- getArgs + progName <- getProgName + let baseDataName = if null args + then progName + else head args + let dataFileName = "data/" ++ baseDataName ++ ".txt" + return dataFileName + +part1 :: [Pair] -> Int +part1 = length . (filter hasContainment) + +part2 :: [Pair] -> Int +part2 = length . (filter overlaps) + +hasContainment, disjoint, overlaps :: Pair -> Bool +hasContainment (assignment1, assignment2) = + (assignment1 `contains` assignment2) || (assignment2 `contains` assignment1) + +disjoint (assignment1, assignment2) = + (assignment1 `before` assignment2) || (assignment2 `before` assignment1) + +overlaps pair = not $ disjoint pair + +contains, before :: Assignment -> Assignment -> Bool +contains (Assignment lower1 upper1) (Assignment lower2 upper2) = + (lower1 <= lower2) && (upper1 >= upper2) + +before (Assignment _lower1 upper1) (Assignment lower2 _upper2) = (upper1 < lower2) + +-- Parse the input file + +pairsP :: Parser [Pair] +pairP :: Parser Pair +assignmentP :: Parser Assignment + +pairsP = pairP `sepBy` endOfLine +pairP = (,) <$> assignmentP <* "," <*> assignmentP + +assignmentP = Assignment <$> decimal <* "-" <*> decimal + +successfulParse :: Text -> [Pair] +successfulParse input = + case parseOnly pairsP input of + Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err + Right pairs -> pairs