parse problem code template

This commit is contained in:
virusdefender 2017-11-26 13:42:38 +08:00
parent 324535474e
commit 945ea5e4e0
4 changed files with 128 additions and 4 deletions

View File

@ -14,6 +14,7 @@ from contest.models import ContestRuleType, ACMContestRank, OIContestRank, Conte
from judge.languages import languages, spj_languages
from options.options import SysOptions
from problem.models import Problem, ProblemRuleType
from problem.utils import parse_problem_template
from submission.models import JudgeStatus, Submission
from utils.cache import cache
from utils.constants import CacheKey
@ -123,16 +124,24 @@ class JudgeDispatcher(DispatcherBase):
cache.lpush(CacheKey.waiting_queue, json.dumps(data))
return
sub_config = list(filter(lambda item: self.submission.language == item["name"], languages))[0]
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": self.submission.code,
"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,

View File

@ -4,6 +4,7 @@ from judge.languages import language_names, spj_language_names
from utils.api import DateTimeTZField, UsernameSerializer, serializers
from .models import Problem, ProblemRuleType, ProblemTag
from .utils import parse_problem_template
class TestCaseUploadForm(forms.Form):
@ -110,9 +111,18 @@ class ContestProblemAdminSerializer(BaseProblemSerializer):
class ProblemSerializer(BaseProblemSerializer):
template = serializers.SerializerMethodField()
def get_template(self, obj):
ret = {}
for lang, code in obj.template.items():
ret[lang] = parse_problem_template(code)["template"]
return ret
class Meta:
model = Problem
exclude = ("contest", "test_case_score", "test_case_id", "visible", "is_public")
exclude = ("contest", "test_case_score", "test_case_id", "visible", "is_public",
"template", "spj_code", "spj_version", "spj_compile_ok")
class ContestProblemSerializer(BaseProblemSerializer):
@ -131,3 +141,54 @@ class ContestProblemSafeSerializer(BaseProblemSerializer):
class ContestProblemMakePublicSerializer(serializers.Serializer):
id = serializers.IntegerField()
display_id = serializers.CharField(max_length=32)
class ExportProblemSerializer(serializers.ModelSerializer):
description = serializers.SerializerMethodField()
input_description = serializers.SerializerMethodField()
output_description = serializers.SerializerMethodField()
test_case_score = serializers.SerializerMethodField()
hint = serializers.SerializerMethodField()
time_limit = serializers.SerializerMethodField()
memory_limit = serializers.SerializerMethodField()
spj = serializers.SerializerMethodField()
template = serializers.SerializerMethodField()
def get_description(self, obj):
return {"format": "html", "value": obj.description}
def get_input_description(self, obj):
return {"format": "html", "value": obj.input_description}
def get_output_description(self, obj):
return {"format": "html", "value": obj.output_description}
def get_hint(self, obj):
return {"format": "html", "value": obj.hint}
def get_test_case_score(self, obj):
return obj.test_case_score if obj.rule_type == ProblemRuleType.OI else []
def get_time_limit(self, obj):
return {"unit": "ms", "value": obj.time_limit}
def get_memory_limit(self, obj):
return {"unit": "MB", "value": obj.memory_limit}
def get_spj(self, obj):
return {"enabled": obj.spj,
"code": obj.spj_code if obj.spj else None,
"language": obj.spj_language if obj.spj else None}
def get_template(self, obj):
ret = {}
for k, v in obj.template.items():
ret[k] = parse_problem_template(v)
return ret
class Meta:
model = Problem
fields = ("_id", "title", "description",
"input_description", "output_description",
"test_case_score", "hint", "time_limit", "memory_limit", "samples",
"template", "spj", "rule_type", "source", "template")

View File

@ -11,10 +11,13 @@ from utils.api.tests import APITestCase
from .models import ProblemTag
from .models import Problem, ProblemRuleType
from .views.admin import TestCaseAPI
from contest.models import Contest
from contest.tests import DEFAULT_CONTEST_DATA
from .views.admin import TestCaseAPI
from .utils import parse_problem_template
DEFAULT_PROBLEM_DATA = {"_id": "A-110", "title": "test", "description": "<p>test</p>", "input_description": "test",
"output_description": "test", "time_limit": 1000, "memory_limit": 256, "difficulty": "Low",
"visible": True, "tags": ["test"], "languages": ["C", "C++", "Java", "Python2"], "template": {},
@ -257,3 +260,44 @@ class ContestProblemTest(ProblemCreateTestBase):
contest.save()
resp = self.client.get(self.url + "?contest_id=" + str(self.contest["id"]))
self.assertSuccess(resp)
class ParseProblemTemplateTest(APITestCase):
def test_parse(self):
template_str = """
//PREPEND BEGIN
aaa
//PREPEND END
//TEMPLATE BEGIN
bbb
//TEMPLATE END
//APPEND BEGIN
ccc
//APPEND END
"""
ret = parse_problem_template(template_str)
self.assertEqual(ret["prepend"], "aaa\n")
self.assertEqual(ret["template"], "bbb\n")
self.assertEqual(ret["append"], "ccc\n")
def test_parse1(self):
template_str = """
//PREPEND BEGIN
aaa
//PREPEND END
//APPEND BEGIN
ccc
//APPEND END
//APPEND BEGIN
ddd
//APPEND END
"""
ret = parse_problem_template(template_str)
self.assertEqual(ret["prepend"], "aaa\n")
self.assertEqual(ret["template"], "")
self.assertEqual(ret["append"], "ccc\n")

10
problem/utils.py Normal file
View File

@ -0,0 +1,10 @@
import re
def parse_problem_template(template_str):
prepend = re.findall("//PREPEND BEGIN\n([\s\S]+?)//PREPEND END", template_str)
template = re.findall("//TEMPLATE BEGIN\n([\s\S]+?)//TEMPLATE END", template_str)
append = re.findall("//APPEND BEGIN\n([\s\S]+?)//APPEND END", template_str)
return {"prepend": prepend[0] if prepend else "",
"template": template[0] if template else "",
"append": append[0] if append else ""}