{-# 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
      Int
t <- IO Int
forall a. Read a => IO a
readLn
      (Int -> IO ()) -> [Int] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> IO ()
f) (IO () -> IO ()) -> (Int -> IO ()) -> Int -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStr (String -> IO ()) -> (Int -> String) -> Int -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
formatGCJ) [Int
1 .. Int
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
  (Int
t : [Int]
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
  (Int -> Interactive a -> Interactive a)
-> Interactive a -> [Int] -> Interactive a
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Interactive a -> Interactive a -> Interactive a
forall a.
Judge (ReaderT InteractiveHandle IO) a
-> Judge (ReaderT InteractiveHandle IO) a
-> Judge (ReaderT InteractiveHandle IO) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) (Interactive a -> Interactive a -> Interactive a)
-> (Int -> Interactive a) -> Int -> Interactive a -> Interactive a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interactive a -> Int -> Interactive a
forall a b. a -> b -> a
const ([Int] -> Interactive a
f [Int]
params)) Interactive a
forall a. Judge (ReaderT InteractiveHandle IO) a
forall (f :: * -> *) a. Alternative f => f a
empty [Int
1 .. Int
t]