示例#1
0
    def judge(data_input, problem_id):
        server = Foo.choose_judge_server()
        submission = data_input
        problem = Problem.objects.get(id=problem_id)

        language = submission['language']
        sub_config = list(
            filter(lambda item: language == item["name"], languages))[0]
        spj_config = {}
        if problem.spj_code:
            for lang in spj_languages:
                if lang["name"] == problem.spj_language:
                    spj_config = lang["spj"]
                    break

        if language in problem.template:
            template = parse_problem_template(problem.template[language])
            code = f"{template['prepend']}\n{submission['code']}\n{template['append']}"
        else:
            code = submission['code']

        data = {
            "language_config": sub_config["config"],
            "src": code,
            "max_cpu_time": problem.time_limit,
            "max_memory": 1024 * 1024 * problem.memory_limit,
            "test_case_id": problem.test_case_id,
            "output": True,
            "spj_version": problem.spj_version,
            "spj_config": spj_config.get("config"),
            "spj_compile_config": spj_config.get("compile"),
            "spj_src": problem.spj_code
        }

        resp = Foo._request(urljoin(server.service_url, "/judge"), data=data)

        if resp["err"]:
            resp['result'] = JudgeStatus.COMPILE_ERROR
            return resp
        else:
            resp["data"].sort(key=lambda x: int(x["test_case"]))
            error_test_case = list(
                filter(lambda case: case["result"] != 0, resp["data"]))

            if not error_test_case:
                result = JudgeStatus.ACCEPTED
            elif problem.rule_type == ProblemRuleType.ACM or len(
                    error_test_case) == len(resp["data"]):
                result = error_test_case[0]["result"]
            else:
                result = JudgeStatus.PARTIALLY_ACCEPTED

        num = resp['data']
        su = num[0]
        output = {"result": result}
        output['data'] = su['output']
        return output
示例#2
0
    def judge(self):
        server = self.choose_judge_server()
        if not server:
            data = {"submission_id": self.submission.id, "problem_id": self.problem.id}
            cache.lpush(CacheKey.waiting_queue, json.dumps(data))
            return

        language = self.submission.language
        sub_config = list(filter(lambda item: language == item["name"], languages))[0]
        spj_config = {}
        if self.problem.spj_code:
            for lang in spj_languages:
                if lang["name"] == self.problem.spj_language:
                    spj_config = lang["spj"]
                    break

        if language in self.problem.template:
            template = parse_problem_template(self.problem.template[language])
            code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}"
        else:
            code = self.submission.code

        data = {
            "language_config": sub_config["config"],
            "src": code,
            "max_cpu_time": self.problem.time_limit,
            "max_memory": 1024 * 1024 * self.problem.memory_limit,
            "test_case_id": self.problem.test_case_id,
            "output": False,
            "spj_version": self.problem.spj_version,
            "spj_config": spj_config.get("config"),
            "spj_compile_config": spj_config.get("compile"),
            "spj_src": self.problem.spj_code
        }

        Submission.objects.filter(id=self.submission.id).update(result=JudgeStatus.JUDGING)

        resp = self._request(urljoin(server.service_url, "/judge"), data=data)
        if resp["err"]:
            self.submission.result = JudgeStatus.COMPILE_ERROR
            self.submission.statistic_info["err_info"] = resp["data"]
            self.submission.statistic_info["score"] = 0
        else:
            resp["data"].sort(key=lambda x: int(x["test_case"]))
            self.submission.info = resp
            self._compute_statistic_info(resp["data"])
            error_test_case = list(filter(lambda case: case["result"] != 0, resp["data"]))
            # ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态
            # OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确
            if not error_test_case:
                self.submission.result = JudgeStatus.ACCEPTED
            elif self.problem.rule_type == ProblemRuleType.ACM or len(error_test_case) == len(resp["data"]):
                self.submission.result = error_test_case[0]["result"]
            else:
                self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED
        self.submission.save()
        self.release_judge_server(server.id)

        if self.contest_id:
            if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \
                    User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest):
                logger.info(
                    "Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id)
                return
            self.update_contest_problem_status()
            self.update_contest_rank()
        else:
            if self.last_result:
                self.update_problem_status_rejudge()
            else:
                self.update_problem_status()

        # 至此判题结束,尝试处理任务队列中剩余的任务
        process_pending_task()
示例#3
0
    def judge(self):
        server = self.choose_judge_server()
        if not server:
            data = {
                "submission_id": self.submission.id,
                "problem_id": self.problem.id
            }
            cache.lpush(CacheKey.waiting_queue, json.dumps(data))
            return

        language = self.submission.language
        sub_config = list(
            filter(lambda item: language == item["name"], languages))[0]
        spj_config = {}
        if self.problem.spj_code:
            for lang in spj_languages:
                if lang["name"] == self.problem.spj_language:
                    spj_config = lang["spj"]
                    break

        if language in self.problem.template:
            template = parse_problem_template(self.problem.template[language])
            code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}"
        else:
            code = self.submission.code

        data = {
            "language_config": sub_config["config"],
            "src": code,
            "max_cpu_time": self.problem.time_limit,
            "max_memory": 1024 * 1024 * self.problem.memory_limit,
            "test_case_id": self.problem.test_case_id,
            "output": False,
            "spj_version": self.problem.spj_version,
            "spj_config": spj_config.get("config"),
            "spj_compile_config": spj_config.get("compile"),
            "spj_src": self.problem.spj_code
        }

        Submission.objects.filter(id=self.submission.id).update(
            result=JudgeStatus.JUDGING)

        service_url = server.service_url
        # not set service_url, it should be a linked container
        if not service_url:
            service_url = settings.DEFAULT_JUDGE_SERVER_SERVICE_URL
        resp = self._request(urljoin(service_url, "/judge"), data=data)
        if resp["err"]:
            self.submission.result = JudgeStatus.COMPILE_ERROR
            self.submission.statistic_info["err_info"] = resp["data"]
            self.submission.statistic_info["score"] = 0
        else:
            resp["data"].sort(key=lambda x: int(x["test_case"]))
            self.submission.info = resp
            self._compute_statistic_info(resp["data"])
            error_test_case = list(
                filter(lambda case: case["result"] != 0, resp["data"]))
            # ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态
            # OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确
            if not error_test_case:
                self.submission.result = JudgeStatus.ACCEPTED
            elif self.problem.rule_type == ProblemRuleType.ACM or len(
                    error_test_case) == len(resp["data"]):
                self.submission.result = error_test_case[0]["result"]
            else:
                self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED
        self.submission.save()
        self.release_judge_server(server.id)

        if self.contest_id:
            self.update_contest_problem_status()
            self.update_contest_rank()
        else:
            self.update_problem_status()

        # 至此判题结束,尝试处理任务队列中剩余的任务
        process_pending_task()
示例#4
0
    def judge(self):
        language = self.submission.language
        sub_config = list(
            filter(lambda item: language == item["name"],
                   SysOptions.languages))[0]
        spj_config = {}
        if self.problem.spj_code:
            for lang in SysOptions.spj_languages:
                if lang["name"] == self.problem.spj_language:
                    spj_config = lang["spj"]
                    break

        if language in self.problem.template:
            template = parse_problem_template(self.problem.template[language])
            code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}"
        else:
            code = self.submission.code

        data = {
            "language_config": sub_config["config"],
            "src": code,
            "max_cpu_time": self.problem.time_limit,
            "max_memory": 1024 * 1024 * self.problem.memory_limit,
            "test_case_id": self.problem.test_case_id,
            "output": True,
            "spj_version": self.problem.spj_version,
            "spj_config": spj_config.get("config"),
            "spj_compile_config": spj_config.get("compile"),
            "spj_src": self.problem.spj_code,
            "io_mode": self.problem.io_mode,
            "output_description": self.problem.output_description,
            "input_str": self.problem.input_str
        }

        with ChooseJudgeServer() as server:
            if not server:
                data = {
                    "submission_id": self.submission.id,
                    "problem_id": self.problem.id
                }
                cache.lpush(CacheKey.waiting_queue, json.dumps(data))
                return
            Submission.objects.filter(id=self.submission.id).update(
                result=JudgeStatus.JUDGING)
            resp = self._request(urljoin(server.service_url, "/judge"),
                                 data=data)

        if not resp:
            Submission.objects.filter(id=self.submission.id).update(
                result=JudgeStatus.SYSTEM_ERROR)
            return

        if resp["err"]:
            self.submission.result = JudgeStatus.COMPILE_ERROR
            self.submission.statistic_info["err_info"] = resp["data"]
            self.submission.statistic_info["score"] = 0
        else:
            resp["data"].sort(key=lambda x: int(x["test_case"]))
            self.submission.info = resp
            self._compute_statistic_info(resp["data"])
            error_test_case = list(
                filter(lambda case: case["result"] != 0, resp["data"]))
            # ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态
            # OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确
            if not error_test_case:
                self.submission.result = JudgeStatus.ACCEPTED
            elif self.problem.rule_type == ProblemRuleType.ACM or len(
                    error_test_case) == len(resp["data"]):
                self.submission.result = error_test_case[0]["result"]
            else:
                self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED
        self.submission.save()

        if self.contest_id:
            if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \
                    User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest):
                logger.info("Contest debug mode, id: " + str(self.contest_id) +
                            ", submission id: " + self.submission.id)
                return
            with transaction.atomic():
                self.update_contest_problem_status()
                self.update_contest_rank()
        else:
            if self.last_result:
                self.update_problem_status_rejudge()
            else:
                self.update_problem_status()

        # 至此判题结束,尝试处理任务队列中剩余的任务
        process_pending_task()
示例#5
0
    def judge(self):
        # 先选择评测机
        server = self.choose_judge_server()
        if not server:
            # 没有Server说明现在被用完,需要等一下
            data = {
                "submission_id": self.submission.id,
                "problem_id": self.problem.id
            }
            # 缓存存放等待任务,返回
            cache.lpush(CacheKey.waiting_queue, json.dumps(data))
            return

        # 提交代码所选择的语言
        language = self.submission.language
        # 提交信息配置sub_config和特殊评判信息配置spj_config
        # 过滤各项名字为系统的选项语言,并保存在语言language,形成一个列表,取到第一项(下标为0)
        sub_config = list(
            filter(lambda item: language == item["name"],
                   SysOptions.languages))[0]
        spj_config = {}

        # 需要进行特殊评判:配置评判语言
        if self.problem.spj_code:
            for lang in SysOptions.spj_languages:
                if lang["name"] == self.problem.spj_language:
                    spj_config = lang["spj"]
                    break

        # 如果提交的语言包含在问题的模板里面,解析模板,重新拼接成新的代码,否则就直接选取配置代码
        if language in self.problem.template:
            template = parse_problem_template(self.problem.template[language])
            code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}"
        else:
            code = self.submission.code

        # 提交数据信息
        data = {
            "language_config": sub_config["config"],
            "src": code,
            "max_cpu_time": self.problem.time_limit,
            "max_memory": 1024 * 1024 * self.problem.memory_limit,
            "test_case_id": self.problem.test_case_id,
            "output": False,
            "spj_version": self.problem.spj_version,
            "spj_config": spj_config.get("config"),
            "spj_compile_config": spj_config.get("compile"),
            "spj_src": self.problem.spj_code
        }

        # 将对应ID的提交信息更新到提交信息数据表,状态由waiting_queue--->JUDGING
        Submission.objects.filter(id=self.submission.id).update(
            result=JudgeStatus.JUDGING)

        # 评判请求发起------->>>>请求后台评判机
        resp = self._request(urljoin(server.service_url, "/judge"), data=data)

        # 根据返回的评测结果信息设置提交信息表字段并保存到数据库表
        if resp["err"]:
            self.submission.result = JudgeStatus.COMPILE_ERROR
            self.submission.statistic_info["err_info"] = resp["data"]
            self.submission.statistic_info["score"] = 0
        else:
            # 成功后,将返回的数据按照test_case顺序排序
            resp["data"].sort(key=lambda x: int(x["test_case"]))
            # 更具响应信息设置提交信息,统计返回的信息
            self.submission.info = resp
            self._compute_statistic_info(resp["data"])
            # 过滤resp["data"]中未通过的测试案例到list,并赋值给error_test_case
            error_test_case = list(
                filter(lambda case: case["result"] != 0, resp["data"]))
            # ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态
            # OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确
            if not error_test_case:
                self.submission.result = JudgeStatus.ACCEPTED
            elif self.problem.rule_type == ProblemRuleType.ACM or len(
                    error_test_case) == len(resp["data"]):
                self.submission.result = error_test_case[0]["result"]
            else:
                self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED
        # 保存提交信息,并释放Server
        self.submission.save()
        self.release_judge_server(server.id)

        if self.contest_id:
            # 如果当前不是正在进行比赛 或者 当前的提交信息对应的用户是比赛的创建者(当前用户是管理员),
            # 日志中记录管理员是在进行调试:显示contest_id和submission.id
            if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \
                    User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest):
                logger.info("Contest debug mode, id: " + str(self.contest_id) +
                            ", submission id: " + self.submission.id)
                return
            # 否则说明是普通用户在进行比赛,更新比赛问题状态和排名
            self.update_contest_problem_status()
            self.update_contest_rank()
        else:
            # 最近的判题(上一次返回的判题)结果不空,就是说评测机Judge Server有信息返回,说明你上一次提交了一次(AC/not AC),这次再提交(往往是没AC时候)
            # 否则就刷新问题状态(例如有一道题被ac,则此题的被ac率应该更新)
            if self.last_result:
                self.update_problem_status_rejudge()
            else:
                self.update_problem_status()

        # 至此判题结束,尝试处理任务队列中剩余的任务
        process_pending_task()
    def judge(self):
        language = self.submission.language
        sub_config = list(
            filter(lambda item: language == item["name"],
                   SysOptions.languages))[0]
        spj_config = {}
        if self.problem.spj_code:
            for lang in SysOptions.spj_languages:
                if lang["name"] == self.problem.spj_language:
                    spj_config = lang["spj"]
                    break

        if language in self.problem.template:
            template = parse_problem_template(self.problem.template[language])
            code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}"
        else:
            code = self.submission.code

        data = {
            "language_config": sub_config["config"],
            "src": code,
            "max_cpu_time": self.problem.time_limit,
            "max_memory": 1024 * 1024 * self.problem.memory_limit,
            "test_case_id": self.problem.test_case_id,
            "output": False,
            "spj_version": self.problem.spj_version,
            "spj_config": spj_config.get("config"),
            "spj_compile_config": spj_config.get("compile"),
            "spj_src": self.problem.spj_code,
            "io_mode": self.problem.io_mode
        }

        with ChooseJudgeServer() as server:
            if not server:
                data = {
                    "submission_id": self.submission.id,
                    "problem_id": self.problem.id
                }
                cache.lpush(CacheKey.waiting_queue, json.dumps(data))
                return
            Submission.objects.filter(id=self.submission.id).update(
                result=JudgeStatus.JUDGING)
            resp = self._request(urljoin(server.service_url, "/judge"),
                                 data=data)

        if not resp:
            Submission.objects.filter(id=self.submission.id).update(
                result=JudgeStatus.SYSTEM_ERROR)
            return

        if resp["err"]:
            self.submission.result = JudgeStatus.COMPILE_ERROR
            self.submission.statistic_info["err_info"] = resp["data"]
            self.submission.statistic_info["score"] = 0
        else:
            resp["data"].sort(key=lambda x: int(x["test_case"]))
            self.submission.info = resp
            self._compute_statistic_info(resp["data"])
            error_test_case = list(
                filter(lambda case: case["result"] != 0, resp["data"]))
            # In ACM mode, if multiple test points are all correct, then AC,
            # otherwise, take the status of the first wrong test point
            # In OI mode, if multiple test points are all correct, AC is used,
            # if all test points are wrong, the first test point state is taken as the first error,
            # otherwise it is partially correct
            if not error_test_case:
                self.submission.result = JudgeStatus.ACCEPTED
            elif self.problem.rule_type == ProblemRuleType.ACM or len(
                    error_test_case) == len(resp["data"]):
                self.submission.result = error_test_case[0]["result"]
            else:
                self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED
        self.submission.save()

        if self.contest_id:
            if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \
                    User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest):
                logger.info("Contest debug mode, id: " + str(self.contest_id) +
                            ", submission id: " + self.submission.id)
                return
            with transaction.atomic():
                self.update_contest_problem_status()
                self.update_contest_rank()
        else:
            if self.last_result:
                self.update_problem_status_rejudge()
            else:
                self.update_problem_status()

        # At this point, the judgment is over, try to process the remaining tasks in the task queue
        process_pending_task()