Today in Advent of Code, we’re counting various interval relationships.
This post is literate Haskell, so here’s the traditional imports header:
import Control.Applicative (liftA2)
import Control.Category ((>>>))
import Data.List.Split (wordsBy)
import Numeric.Interval (Interval,(...),contains,intersection,isSubsetOf,null)
import Prelude hiding (null)Since there’s really not much thinking involved in doing the interval relationship part, let’s spend some quality time parsing.
main :: IO ()
main = interact $First, split by lines.
lines >>>On each line, extract the intervals.
map (wordsBy (== ',')) >>>For each interval, split the lower and upper bound.
(map . map) (wordsBy (== '-')) >>>Parse the bounds as integers. (No need to actually specify “integer” anywhere, the types are inferred. What’s not is that we’re actually converting.)
(map . map . map) read >>>Convert the bound pairs to actual Intervals.
(map . map) (uncurry (...) . listToPair) >>>Perform the same kind of functional hackery we did on day 1 to compute both parts using the same pipeline.
flip countIf >>>
flip map [part1,part2] >>>
showBoth parts have the same core: count the number of interval pairs who are in a certain relationship, so that much was factored. Now the actual specificities.
part1,part2 :: (Interval Int,Interval Int) -> BoolIn part 1, we’re looking for intervals pairs where one contains the other. There are multiple ways to do this; here’s one.
part1 = liftA2 (||) (uncurry contains) (uncurry isSubsetOf)In part 2, we’re looking for intersecting intervals. I couldn’t find a function to do directly this in the library I’m using, but it’s simple enough to reproduce.
part2 = not . null . uncurry intersectionFor completeness, a couple of helper functions.
listToPair :: [a] -> (a,a)
listToPair [a,b] = (a,b)
countIf :: ((a,a) -> Bool) -> [[a]] -> Int
countIf p = filter (listToPair >>> p) >>> lengthThis concludes today’s puzzle. I’m sorry I had to spice it up with pointless twiddling, I’m sure the following days will be more interesting. See you then!