41 lines
1.3 KiB
Haskell
Raw Normal View History

2025-12-08 13:40:55 +00:00
module Puzzles.Day8 (puzzle) where
import Pre
2025-12-08 21:58:47 +00:00
import Data.DisjointSet qualified as DS
import Data.Text.Lazy qualified as TL
import Linear.Metric
import Linear.V3
2025-12-08 13:40:55 +00:00
puzzle :: Puzzle
puzzle =
Puzzle
{ number = 8
, parser = \isRealData -> (if isRealData then 1000 else 10,) <$> (V3 <$> decimal <* single ',' <*> decimal <* single ',' <*> decimal) `sepEndBy` newline
2025-12-08 13:40:55 +00:00
, parts =
[ uncurry \n -> TL.show
2025-12-08 21:58:47 +00:00
. product
. take 3
. sortOn Down
. map length
. DS.toLists
. snd
. (!! n)
. connectBoxes
, uncurry . const $ TL.show
2025-12-08 22:01:49 +00:00
. maybe (error "sets never unified") (\((V3 x1 _ _, V3 x2 _ _), _) -> x1 * x2)
. lastMay
. takeWhile ((> 1) . DS.sets . snd)
. connectBoxes
2025-12-08 13:40:55 +00:00
]
, extraTests = mempty
}
2025-12-08 21:58:47 +00:00
connectBoxes :: [V3 Int] -> [((V3 Int, V3 Int), DS.DisjointSet (V3 Int))]
connectBoxes boxes = zip allPairs $ scanl (flip $ uncurry DS.union) (foldMap DS.singleton boxes) allPairs
where
allPairs = sortOn (quadrance . uncurry (-)) $ filter (uncurry (/=)) $ allUnorderedPairs boxes
allUnorderedPairs :: [a] -> [(a, a)]
allUnorderedPairs = concat . join (zipWith (flip $ map . (,)) . tails)