/// <summary> /// 获取测试数据目录下的SPJ程序路径 /// </summary> /// <param name="problemId">问题ID</param> /// <param name="lang">语言</param> /// <returns>SPJ程序路径</returns> public static string GetSpjProgramPathInTestData(int problemId, ProgramLangConfig lang) { string spjDirectory = GetSpjDirectoryInTestData(problemId); string programExt = Path.GetExtension(lang.ProgramFileName).TrimStart('.').ToLower(); string sourceExt = lang.SourceCodeFileExtension.Split('|')[0].ToLower(); string path = Path.Combine(spjDirectory, SPJ_PROGRAM_FILENAME + "." + sourceExt + "." + programExt); return(PathHelper.GetBaseAbsolutePath(path)); }
/// <summary> /// 创建JudgeTask实例 /// </summary> /// <param name="submitId">提交ID</param> /// <param name="problemId">问题ID</param> /// <param name="dataVersion">测试数据版本</param> /// <param name="language">语言</param> /// <param name="sourceCode">源代码</param> /// <param name="author">作者</param> /// <param name="timeLimit">时间限制</param> /// <param name="memoryLimit">内存限制</param> /// <param name="judgeAllCases">是否评测全部样例(即使遇到错误答案)</param> /// <param name="judgeType">评测类型</param> /// <returns>JudgeTask实例</returns> public static JudgeContext Create(int submitId, int problemId, string dataVersion, string language, string sourceCode, string author = "", int timeLimit = 1000, int memoryLimit = 262144, bool judgeAllCases = false, JudgeType judgeType = JudgeType.ProgramJudge) { ILangConfig langConfig = ConfigManager.GetLanguageConfig(language); if (langConfig == null) { throw new JudgeException("Unsupported language: " + language); } // 分配评测临时目录 string tempDirectory = RandomString.Next(16); if (langConfig is ProgramLangConfig) { ProgramLangConfig langCfg = langConfig as ProgramLangConfig; tempDirectory = GetTempDirectory(langCfg.JudgeDirectory); UpdatePathInfo(langCfg, tempDirectory); } double timeCompensation = GetTimeCompensation(langConfig); JudgeTask task = new JudgeTask { SubmitId = submitId, ProblemId = problemId, DataVersion = dataVersion, Language = language, SourceCode = sourceCode, Author = author, TimeLimit = (int)(timeLimit / timeCompensation), MemoryLimit = memoryLimit, JudgeAllCases = judgeAllCases, JudgeType = judgeType }; JudgeResult result = new JudgeResult { SubmitId = task.SubmitId, ProblemId = task.ProblemId, Author = task.Author, JudgeDetail = "", MemoryCost = Config.MinimumMemoryCost, TimeCost = 0, PassRate = 0, ResultCode = JudgeResultCode.Accepted }; return(new JudgeContext(task, result, tempDirectory, langConfig)); }
/// <summary> /// 更新语言配置中的路径信息 /// </summary> private static void UpdatePathInfo(ProgramLangConfig langConfig, string tempDirectory) { string appDirectory = PathHelper.GetBaseAbsolutePath(""); if (!Directory.Exists(tempDirectory)) { Directory.CreateDirectory(tempDirectory); } // 替换<tempdir>字段 langConfig.CompilerPath = ReplacePathInfo(langConfig.CompilerPath, tempDirectory, appDirectory); langConfig.CompilerWorkDirectory = ReplacePathInfo(langConfig.CompilerWorkDirectory, tempDirectory, appDirectory); langConfig.CompilerArgs = ReplacePathInfo(langConfig.CompilerArgs, tempDirectory, appDirectory); langConfig.RunnerPath = ReplacePathInfo(langConfig.RunnerPath, tempDirectory, appDirectory); langConfig.RunnerWorkDirectory = ReplacePathInfo(langConfig.RunnerWorkDirectory, tempDirectory, appDirectory); langConfig.RunnerArgs = ReplacePathInfo(langConfig.RunnerArgs, tempDirectory, appDirectory); }
/// <summary> /// 创建SPJ的JudgeContext, 用于编译运行SPJ程序 /// </summary> /// <param name="originContext">源评测任务</param> /// <returns>SPJ的JudgeTask</returns> public static JudgeContext CreateSpjJudgeContext(JudgeContext originContext) { JudgeContext newContext = originContext.Clone() as JudgeContext; string spjSourceFilePath = FindSpjSourceFileInTestData(newContext.Task.ProblemId); if (spjSourceFilePath == null) //没有SPJ程序源代码, 无法评测 { throw new JudgeException("No special judge program exception!"); } newContext.Task.SourceCode = File.ReadAllText(spjSourceFilePath); newContext.LangConfig = GetLangConfigBySourceFilePath(spjSourceFilePath); ProgramLangConfig langConfig = newContext.LangConfig as ProgramLangConfig; newContext.Task.Language = newContext.LangConfig.Name; string spjDir = GetSpjDirectoryInJudger(originContext) + "\\"; string appDir = PathHelper.GetBaseAbsolutePath(""); // 替换<tempdir>和<appdir>字段 langConfig.CompilerPath = langConfig.CompilerPath.Replace("<tempdir>", spjDir).Replace("<appdir>", appDir); langConfig.CompilerWorkDirectory = langConfig.CompilerWorkDirectory.Replace("<tempdir>", spjDir) .Replace("<appdir>", appDir); langConfig.CompilerArgs = langConfig.CompilerArgs.Replace("<tempdir>", spjDir).Replace("<appdir>", appDir); langConfig.RunnerPath = langConfig.RunnerPath.Replace("<tempdir>", spjDir).Replace("<appdir>", appDir); langConfig.RunnerWorkDirectory = langConfig.RunnerWorkDirectory.Replace("<tempdir>", spjDir) .Replace("<appdir>", appDir); langConfig.RunnerArgs = langConfig.RunnerArgs.Replace("<tempdir>", spjDir).Replace("<appdir>", appDir); newContext.TempDirectory = spjDir; if (!Directory.Exists(spjDir)) { Directory.CreateDirectory(spjDir); } return(newContext); }
/// <summary> /// 获取SPJ可执行程序 /// </summary> /// <param name="problemId">问题ID</param> /// <param name="index">索引</param> /// <returns>SPJ程序</returns> public static SpecialJudgeProgram GetSpecialJudgeProgramFile(int problemId, int index = 0) { lock (GetDataLock(problemId)) { string programPath = SpjManager.FindSpjProgramInTestData(problemId, index); if (programPath == null) { return(null); } ProgramLangConfig langConfig = SpjManager.GetLangConfigByProgramPath(programPath); if (langConfig == null) { return(null); } return(new SpecialJudgeProgram { LangConfiguration = langConfig, Program = File.ReadAllBytes(programPath) }); } }
private static ProgramLangConfig[] GetDefaultLangConfigs() { List <ProgramLangConfig> langConfigs = new List <ProgramLangConfig>(); char sparChar = Path.DirectorySeparatorChar; ProgramLangConfig c = new ProgramLangConfig { Name = "c", IsDbConfig = false, NeedCompile = true, RunningInVm = false, SourceCodeFileName = "src.c", SourceCodeFileExtension = "c", ProgramFileName = "program.exe", UseUtf8 = true, MaxCompileTime = 20000, JudgeDirectory = "JudgeTemp" + sparChar + "CJudge", CompilerPath = "gcc", CompilerWorkDirectory = "<tempdir>", CompilerArgs = "src.c -o program.exe", RunnerPath = "<tempdir>program.exe", RunnerWorkDirectory = "<tempdir>", RunnerArgs = "", OutputLimit = 67108864, TimeCompensation = 1.0 }; ProgramLangConfig cpp = new ProgramLangConfig { Name = "cpp", IsDbConfig = false, NeedCompile = true, RunningInVm = false, SourceCodeFileName = "src.cpp", SourceCodeFileExtension = "cc|cpp", ProgramFileName = "program.exe", UseUtf8 = true, MaxCompileTime = 20000, JudgeDirectory = "JudgeTemp" + sparChar + "CppJudge", CompilerPath = "g++", CompilerWorkDirectory = "<tempdir>", CompilerArgs = "src.cpp -o program.exe", RunnerPath = "<tempdir>program.exe", RunnerWorkDirectory = "<tempdir>", RunnerArgs = "", OutputLimit = 67108864, TimeCompensation = 1.0 }; ProgramLangConfig java = new ProgramLangConfig { Name = "java", IsDbConfig = false, NeedCompile = true, RunningInVm = true, SourceCodeFileName = "Main.java", SourceCodeFileExtension = "java", ProgramFileName = "Main.class", UseUtf8 = false, MaxCompileTime = 30000, JudgeDirectory = "JudgeTemp" + sparChar + "JavaJudge", CompilerPath = "javac", CompilerWorkDirectory = "<tempdir>", CompilerArgs = "-encoding utf-8 Main.java", RunnerPath = "java", RunnerWorkDirectory = "<tempdir>", RunnerArgs = "Main", OutputLimit = 67108864, TimeCompensation = 1.0 }; ProgramLangConfig python = new ProgramLangConfig { Name = "python", IsDbConfig = false, NeedCompile = false, RunningInVm = true, SourceCodeFileName = "src.py", SourceCodeFileExtension = "py", ProgramFileName = "src.py", UseUtf8 = true, MaxCompileTime = 20000, JudgeDirectory = "JudgeTemp" + sparChar + "PythonJudge", CompilerPath = "", CompilerWorkDirectory = "", CompilerArgs = "", RunnerPath = "python", RunnerWorkDirectory = "<tempdir>", RunnerArgs = "<tempdir>src.py", OutputLimit = 67108864, TimeCompensation = 1.0 }; langConfigs.Add(c); langConfigs.Add(cpp); langConfigs.Add(java); langConfigs.Add(python); return(langConfigs.ToArray()); }