import _ = require('lodash'); import winston = require('winston'); export interface JudgeResultSubmit { taskId: number; time: number; memory: number; score: number; statusNumber: number; statusString: string; result: string; } import { JudgeResult, TaskResult, TaskStatus, ErrorType, SubtaskResult, TestCaseResult, TestCaseDetails } from './interfaces'; const compileError = "Compile Error", systemError = "System Error", testdataError = "No Testdata"; export const statusToString = {}; statusToString[TaskResult.Accepted] = "Accepted"; statusToString[TaskResult.WrongAnswer] = "Wrong Answer"; statusToString[TaskResult.PartiallyCorrect] = "Partially Correct"; statusToString[TaskResult.MemoryLimitExceeded] = "Memory Limit Exceeded"; statusToString[TaskResult.TimeLimitExceeded] = "Time Limit Exceeded"; statusToString[TaskResult.OutputLimitExceeded] = "Output Limit Exceeded"; statusToString[TaskResult.RuntimeError] = "Runtime Error"; statusToString[TaskResult.FileError] = "File Error"; statusToString[TaskResult.JudgementFailed] = "Judgement Failed"; statusToString[TaskResult.InvalidInteraction] = "Invalid Interaction"; export function firstNonAC(t: TaskResult[]): TaskResult { if (t.every(v => v === TaskResult.Accepted)) { return TaskResult.Accepted } else { return t.find(r => r !== TaskResult.Accepted); } } export function convertResult(id: number, source: JudgeResult): JudgeResultSubmit { winston.debug(`Converting result for ${id}`, source); let time = -1, memory = -1, score = 0, done = true, statusString = null; if (source.compileStatus === TaskStatus.Failed) { statusString = compileError; score = 0; } else if (source.error != null) { done = false; score = NaN; if (source.error === ErrorType.TestDataError) { statusString = testdataError; } else { statusString = systemError; } } else if (source.subtasks != null) { if (source.subtasks.some(s => s.score === NaN)) { score = NaN; statusString = systemError; } else { score = _.sum(source.subtasks.map(s => s.score)); const forEveryTestcase = function (map: (v: TestCaseDetails) => TParam, reduce: (v: TParam[]) => TParam): TParam { return reduce(source.subtasks.map(s => reduce(s.cases.filter(c => c.result != null).map(c => map(c.result))))); } time = forEveryTestcase(c => c.time, _.sum); memory = forEveryTestcase(c => c.memory, _.max); const finalResult = forEveryTestcase(c => c.type, firstNonAC); statusString = statusToString[finalResult]; } } const result = { taskId: id, time: time, memory: memory, score: score, statusNumber: done ? TaskStatus.Done : TaskStatus.Failed, statusString: statusString, result: JSON.stringify(source) }; winston.debug(`Result for ${id}`, result); return result; }