let
(i,z) = splitAt n l
go _ [] = []
go p (a:r) = (p,a) : go (drop 1 p ++ [a]) r
in go i z
valid p n = not $ null $ do
(a:r) <- tails $ sort $ filter (< n) p
let t = n - a
(_,ge) <- [break (>= t) r]
(_:_) <- [takeWhile (== t) ge]
return ()
snd . head . filter (not . uncurry valid) . stretches 25
go 0 [] where
go es e r = case es `compare` t of
LT -> case r of
(h:r') -> go (es + h) (e ++ [h]) r'
[] -> []
EQ -> e : let
(d:r') = e
in go (es - d) r' r
GT -> let
(d:r') = e
in go (es - d) r' r
head $ do
l'@(_:_:_) <- stretchesWithSum e l
Just (MinMax a h) <- pure $ foldMap (Just . minMax) l'
return (a + h)
data MinMax a = MinMax a a
MinMax l1 h1 <> MinMax l2 h2 = MinMax (min l1 l2) (max h1 h2)
join MinMax
do
[fn] <- getArgs
d <- (map (read :: String -> Integer) . words) <$> readFile fn
let p1 = part1 d
print p1
print $ part2 d p1