Done day 5
[advent-of-code-22.git] / advent04 / Main.hs
1 -- Writeup at https://work.njae.me.uk/2022/12/04/advent-of-code-2022-day-4/
2
3 import System.Environment
4 import Data.Text (Text)
5 import qualified Data.Text.IO as TIO
6 import Data.Attoparsec.Text hiding (Result)
7 -- import Control.Applicative
8
9 data Assignment = Assignment Int Int deriving (Show, Eq)
10 type Pair = (Assignment, Assignment)
11
12 main :: IO ()
13 main =
14 do dataFileName <- getDataFileName
15 text <- TIO.readFile dataFileName
16 let pairs = successfulParse text
17 print $ part1 pairs
18 print $ part2 pairs
19
20 getDataFileName :: IO String
21 getDataFileName =
22 do args <- getArgs
23 progName <- getProgName
24 let baseDataName = if null args
25 then progName
26 else head args
27 let dataFileName = "data/" ++ baseDataName ++ ".txt"
28 return dataFileName
29
30 part1 :: [Pair] -> Int
31 part1 = length . (filter hasContainment)
32
33 part2 :: [Pair] -> Int
34 part2 = length . (filter overlaps)
35
36 hasContainment, disjoint, overlaps :: Pair -> Bool
37 hasContainment (assignment1, assignment2) =
38 (assignment1 `contains` assignment2) || (assignment2 `contains` assignment1)
39
40 disjoint (assignment1, assignment2) =
41 (assignment1 `before` assignment2) || (assignment2 `before` assignment1)
42
43 overlaps = not . disjoint
44
45 contains, before :: Assignment -> Assignment -> Bool
46 contains (Assignment lower1 upper1) (Assignment lower2 upper2) =
47 (lower1 <= lower2) && (upper1 >= upper2)
48
49 before (Assignment _lower1 upper1) (Assignment lower2 _upper2) =
50 (upper1 < lower2)
51
52 -- Parse the input file
53
54 pairsP :: Parser [Pair]
55 pairP :: Parser Pair
56 assignmentP :: Parser Assignment
57
58 pairsP = pairP `sepBy` endOfLine
59 pairP = (,) <$> assignmentP <* "," <*> assignmentP
60
61 assignmentP = Assignment <$> decimal <* "-" <*> decimal
62
63 successfulParse :: Text -> [Pair]
64 successfulParse input =
65 case parseOnly pairsP input of
66 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
67 Right pairs -> pairs