{-# LANGUAGE LambdaCase #-}

module Control.GCJ where

import Control.Applicative
import Control.Monad.Trans
import System.Environment

import Control.Monad.Interactive

formatGCJ :: Int -> String
formatGCJ :: Int -> String
formatGCJ Int
i = String
"Case #" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String -> String
forall a. Show a => a -> String -> String
shows Int
i String
": "

withGCJ :: IO () -> IO ()
withGCJ :: IO () -> IO ()
withGCJ IO ()
f =
  IO [String]
getArgs IO [String] -> ([String] -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    [String
"--debug"] -> IO ()
f
    [] -> do
      t <- IO Int
forall a. Read a => IO a
readLn
      mapM_ ((*> f) . putStr . formatGCJ) [1 .. t]
    [String]
args -> String -> IO ()
forall a. HasCallStack => String -> a
error (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall a. Show a => a -> String
show [String]
args

withGCJInteractive :: ([Int] -> Interactive a) -> IO ()
withGCJInteractive :: forall a. ([Int] -> Interactive a) -> IO ()
withGCJInteractive [Int] -> Interactive a
f = Interactive a -> IO ()
forall a. Interactive a -> IO ()
withInteractive (Interactive a -> IO ()) -> Interactive a -> IO ()
forall a b. (a -> b) -> a -> b
$ do
  (t : params) <- (String -> Int) -> [String] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map String -> Int
forall a. Read a => String -> a
read ([String] -> [Int]) -> (String -> [String]) -> String -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words (String -> [Int])
-> Judge (ReaderT InteractiveHandle IO) String
-> Judge (ReaderT InteractiveHandle IO) [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT InteractiveHandle IO String
-> Judge (ReaderT InteractiveHandle IO) String
forall (m :: * -> *) a. Monad m => m a -> Judge m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ReaderT InteractiveHandle IO String
forall (m :: * -> *). MonadInteractive m => m String
recvLine
  foldr ((<|>) . const (f params)) empty [1 .. t]