content: -- |
  -- Module      : AOC.Challenge.Day01
  -- Copyright   : (c) Justin Le 2018
  -- License     : BSD3
  --
  -- Maintainer  : justin@jle.im
  -- Stability   : experimental
  -- Portability : non-portable
  --
  -- Day 1!  See "AOC.Solver" for the types used in this module!
  
  module AOC.Challenge.Day01 (day01a, day01b) where
  
  import           AOC.Common (firstRepeated)
  import           AOC.Solver ((:~>)(..))
  import           Text.Read  (readMaybe)
  
  -- | We need this because 'read' can't handle positive signs in front of
  -- numbers.
  parseItem :: String -> Maybe Int
  parseItem = readMaybe . filter (/= '+')
  
  -- | Here we have a basic sum of numbers.
  day01a :: [Int] :~> Int
  day01a = MkSol
      { sParse = traverse parseItem . lines
      , sShow  = show
      , sSolve = Just . sum
      }
  
  -- | Here we compute a running sum on an infinitely repeated list of
  -- inputs, and then use 'firstRepeated' to get the first repeated item in
  -- the list of running sums.
  day01b :: [Int] :~> Int
  day01b = MkSol
      { sParse = traverse parseItem . lines
      , sShow  = show
      , sSolve = firstRepeated        -- > get first repeated sum
               . scanl (+) 0          -- > compute running sum
               . cycle                -- > infinitely cycle input
      }
  