From 6db626fdd0b191829d9a3ba276fc8c027fe67274 Mon Sep 17 00:00:00 2001
From: Neil Smith <NeilNjae@users.noreply.github.com>
Date: Sun, 4 Dec 2022 10:42:34 +0000
Subject: [PATCH] Alternative, using an interval library

---
 advent-of-code22.cabal    |  7 ++++-
 advent04/Main-interval.hs | 57 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 advent04/Main-interval.hs

diff --git a/advent-of-code22.cabal b/advent-of-code22.cabal
index a374b42..ca41874 100644
--- a/advent-of-code22.cabal
+++ b/advent-of-code22.cabal
@@ -108,4 +108,9 @@ executable advent03
 executable advent04
   import: common-extensions, build-directives
   main-is: advent04/Main.hs
-  build-depends: text, attoparsec
\ No newline at end of file
+  build-depends: text, attoparsec
+
+executable advent04i
+  import: common-extensions, build-directives
+  main-is: advent04/Main-interval.hs
+  build-depends: text, attoparsec, intervals
diff --git a/advent04/Main-interval.hs b/advent04/Main-interval.hs
new file mode 100644
index 0000000..7888fae
--- /dev/null
+++ b/advent04/Main-interval.hs
@@ -0,0 +1,57 @@
+-- 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 Numeric.Interval hiding (null)
+-- import Control.Applicative
+
+type Assignment = Interval Int
+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 $ uncurry (==?))
+
+hasContainment :: Pair -> Bool
+hasContainment (assignment1, assignment2) = 
+  (assignment1 `contains` assignment2) || (assignment2 `contains` assignment1)
+
+
+-- Parse the input file
+
+pairsP :: Parser [Pair]
+pairP :: Parser Pair
+assignmentP :: Parser Assignment
+
+pairsP = pairP `sepBy` endOfLine
+pairP = (,) <$> assignmentP <* "," <*> assignmentP
+
+assignmentP = (...) <$> decimal <* "-" <*> decimal
+
+successfulParse :: Text -> [Pair]
+successfulParse input = 
+  case parseOnly pairsP input of
+    Left  _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
+    Right pairs -> pairs
-- 
2.43.0