module Lambdajudge
(
muevalAvlbl,
gradeSubmission,
runLJMonad
) where
import System.Environment
import System.FilePath
import System.Timeout
import System.Process
import System.Exit
import System.IO
import Data.List
import Control.Monad.State
import Control.Monad.Writer
import Control.Monad.Error
import Control.Monad.Identity
import Control.Exception
import DataStructures
import Utility
runSubmission :: MuevalCommand -> LJMonad StatusCode
runSubmission mue = do
let options = ["-t", show $ maxRunTime mue] ++
["-e", "lines (" ++ expression mue ++ " " ++ show (testData mue) ++ ") == lines (" ++ (trim . show) (ansData mue) ++ ")"] ++
["-l", solutionFile mue]
(status,out,err) <- liftIO $ readProcessWithExitCode "mueval" options ""
tell $ show (status,out,err)
liftIO $ print (status,out,err)
modify succ
case status of
ExitSuccess -> case err of
"" -> if (read out :: Bool)
then return AC
else return WA
ExitFailure a -> if "Time limit exceeded" `isInfixOf` err
then return TLE
else error err
gradeSubmission :: Problem -> FilePath -> LJMonad [StatusCode]
gradeSubmission prob solutionFile = do
let computations = map (\i -> uncurry (MuevalCommand "solution") (testCases prob!!i) solutionFile (timeLimit prob)) [0..length (testCases prob) 1]
mapM runSubmission computations
runLJMonad :: Num s => WriterT w (StateT s (ErrorT e m)) a -> m (Either e ((a, w), s))
runLJMonad = runErrorT . flip runStateT 0 . runWriterT
catchAny :: IO a -> (SomeException -> IO a) -> IO a
catchAny = Control.Exception.catch
muevalAvlbl :: IO Bool
muevalAvlbl = do
res <- liftIO $ catchAny (readProcessWithExitCode "mueval" ["-e","1+1"] "") $ \e -> do
putStrLn "Got an exception."
return (ExitFailure 1,"","")
case res of
(ExitSuccess,out,err) -> return True
otherwise -> return False
createContest :: IO Problem
createContest = do
let dir = "test/contest1/Q1/"
t1 <- getFileContents (dir </> "input00.txt")
s1 <- getFileContents (dir </> "output00.txt")
t2 <- getFileContents (dir </> "input02.txt")
s2 <- getFileContents (dir </> "output02.txt")
ps1 <- getFileContents (dir </> "ProblemStatement")
sol1 <- getFileContents (dir </> "Solution/Solution.hs")
return $ Problem ps1 [(t1,s1),(t2,s2)] sol1 5
test = do
prob1 <- Lambdajudge.createContest
runLJMonad $ gradeSubmission prob1 "test/contest1/Q1/Solution/Solution.hs"