content: -- |
  -- Module      : AOC.Challenge.Day25
  -- Copyright   : (c) Justin Le 2018
  -- License     : BSD3
  --
  -- Maintainer  : justin@jle.im
  -- Stability   : experimental
  -- Portability : non-portable
  --
  -- Day 25.  See "AOC.Solver" for the types used in this module!
  
  module AOC.Challenge.Day25 (
      day25a
    ) where
  
  import           AOC.Common      (mannDist, clearOut)
  import           AOC.Solver      ((:~>)(..))
  import           Data.Char       (isDigit)
  import           Data.Graph      (Graph)
  import           Data.Witherable (mapMaybe)
  import           Linear          (V4(..))
  import qualified Data.Graph      as G
  
  constellationGraph :: [V4 Int] -> Graph
  constellationGraph xs = g
    where
      (g, _, _) = G.graphFromEdges (map collect xs)
      collect x = ((), x, filter ((<= 3) . mannDist x) xs)
  
  day25a :: [V4 Int] :~> Int
  day25a = MkSol
      { sParse = Just . parse25
      , sShow  = show
      , sSolve = Just . length . G.scc . constellationGraph
      }
  
  parse25 :: String -> [V4 Int]
  parse25 = mapMaybe (go . map read . words . clearOut d) . lines
    where
      d '-' = False
      d c   = not (isDigit c)
      go [x,y,z,r] = Just $ V4 x y z r
      go _         = Nothing
  
  