2025-12-05 12:56:40 +00:00
|
|
|
module Puzzles.Day5 (puzzle) where
|
|
|
|
|
|
2025-12-08 12:48:49 +00:00
|
|
|
import Pre
|
|
|
|
|
|
2025-12-05 13:16:33 +00:00
|
|
|
import Data.Text.Lazy qualified as TL
|
2025-12-05 12:56:40 +00:00
|
|
|
|
|
|
|
|
puzzle :: Puzzle
|
|
|
|
|
puzzle =
|
|
|
|
|
Puzzle
|
|
|
|
|
{ number = 5
|
2025-12-08 22:42:29 +00:00
|
|
|
, parser = const do
|
2025-12-08 23:44:43 +00:00
|
|
|
ranges <- (Range <$> decimal <* single '-' <*> decimal) `sepEndBy` newline
|
2025-12-05 13:16:33 +00:00
|
|
|
void newline
|
2025-12-08 23:44:43 +00:00
|
|
|
vals <- decimal `sepEndBy` newline
|
2025-12-05 13:16:33 +00:00
|
|
|
pure (ranges, vals)
|
2025-12-05 12:56:40 +00:00
|
|
|
, parts =
|
2025-12-05 13:16:33 +00:00
|
|
|
[ \(ranges, vals) ->
|
|
|
|
|
TL.show
|
|
|
|
|
. length
|
2025-12-05 14:39:42 +00:00
|
|
|
. filter (flip any ranges . isInRange)
|
|
|
|
|
$ vals
|
2025-12-05 15:36:12 +00:00
|
|
|
, TL.show
|
|
|
|
|
. sum
|
|
|
|
|
. map rangeLength
|
|
|
|
|
. foldr addInterval []
|
|
|
|
|
. sortOn (Down . (.lower))
|
|
|
|
|
. fst
|
2025-12-05 12:56:40 +00:00
|
|
|
]
|
|
|
|
|
, extraTests = mempty
|
|
|
|
|
}
|
2025-12-05 13:16:33 +00:00
|
|
|
|
|
|
|
|
data Range = Range
|
|
|
|
|
{ lower :: Int
|
|
|
|
|
, upper :: Int
|
|
|
|
|
}
|
|
|
|
|
deriving (Eq, Ord, Show)
|
|
|
|
|
|
2025-12-05 15:36:12 +00:00
|
|
|
rangeLength :: Range -> Int
|
|
|
|
|
rangeLength r = r.upper - r.lower + 1
|
|
|
|
|
|
2025-12-05 13:16:33 +00:00
|
|
|
isInRange :: Int -> Range -> Bool
|
|
|
|
|
isInRange n r = n >= r.lower && n <= r.upper
|
2025-12-05 15:36:12 +00:00
|
|
|
|
|
|
|
|
extend :: Int -> Range -> Range
|
|
|
|
|
extend upper r = r{upper = max r.upper upper}
|
|
|
|
|
|
|
|
|
|
addInterval :: Range -> [Range] -> [Range]
|
|
|
|
|
addInterval new = \case
|
|
|
|
|
[] -> [new]
|
|
|
|
|
(r : rs) ->
|
|
|
|
|
if isInRange new.lower r
|
|
|
|
|
then extend new.upper r : rs
|
|
|
|
|
else new : r : rs
|