{-# Language QuasiQuotes, ImportQualifiedPost #-}
module Main (main) where
import Advent (format, partialSums)
import Data.Maybe (fromJust)
import Data.Set qualified as Set
main :: IO ()
IO ()
main =
do [Integer]
inp <- [format|2018 1 ((%+|)%ld%n)*|]
Integer -> IO ()
forall a. Show a => a -> IO ()
print ([Integer] -> Integer
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Integer]
inp)
Integer -> IO ()
forall a. Show a => a -> IO ()
print ([Integer] -> Integer
part2 [Integer]
inp)
part2 :: [Integer] -> Integer
part2 :: [Integer] -> Integer
part2 = Maybe Integer -> Integer
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Integer -> Integer)
-> ([Integer] -> Maybe Integer) -> [Integer] -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Integer] -> Maybe Integer
forall a. Ord a => [a] -> Maybe a
firstDuplicate ([Integer] -> Maybe Integer)
-> ([Integer] -> [Integer]) -> [Integer] -> Maybe Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Integer] -> [Integer]
forall a. Num a => [a] -> [a]
partialSums ([Integer] -> [Integer])
-> ([Integer] -> [Integer]) -> [Integer] -> [Integer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Integer] -> [Integer]
forall a. HasCallStack => [a] -> [a]
cycle
firstDuplicate :: Ord a => [a] -> Maybe a
firstDuplicate :: forall a. Ord a => [a] -> Maybe a
firstDuplicate = Set a -> [a] -> Maybe a
forall {a}. Ord a => Set a -> [a] -> Maybe a
go Set a
forall a. Set a
Set.empty
where
go :: Set a -> [a] -> Maybe a
go Set a
_ [] = Maybe a
forall a. Maybe a
Nothing
go Set a
seen (a
x:[a]
xs)
| a
x a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
seen = a -> Maybe a
forall a. a -> Maybe a
Just a
x
| Bool
otherwise = Set a -> [a] -> Maybe a
go (a -> Set a -> Set a
forall a. Ord a => a -> Set a -> Set a
Set.insert a
x Set a
seen) [a]
xs