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 judge.languages import languages, spj_languages
from options.options import SysOptions from options.options import SysOptions
from problem.models import Problem, ProblemRuleType from problem.models import Problem, ProblemRuleType
from problem.utils import parse_problem_template
from submission.models import JudgeStatus, Submission from submission.models import JudgeStatus, Submission
from utils.cache import cache from utils.cache import cache
from utils.constants import CacheKey from utils.constants import CacheKey
@ -123,16 +124,24 @@ class JudgeDispatcher(DispatcherBase):
cache.lpush(CacheKey.waiting_queue, json.dumps(data)) cache.lpush(CacheKey.waiting_queue, json.dumps(data))
return 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 = {} spj_config = {}
if self.problem.spj_code: if self.problem.spj_code:
for lang in spj_languages: for lang in spj_languages:
if lang["name"] == self.problem.spj_language: if lang["name"] == self.problem.spj_language:
spj_config = lang["spj"] spj_config = lang["spj"]
break 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 = { data = {
"language_config": sub_config["config"], "language_config": sub_config["config"],
"src": self.submission.code, "src": code,
"max_cpu_time": self.problem.time_limit, "max_cpu_time": self.problem.time_limit,
"max_memory": 1024 * 1024 * self.problem.memory_limit, "max_memory": 1024 * 1024 * self.problem.memory_limit,
"test_case_id": self.problem.test_case_id, "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 utils.api import DateTimeTZField, UsernameSerializer, serializers
from .models import Problem, ProblemRuleType, ProblemTag from .models import Problem, ProblemRuleType, ProblemTag
from .utils import parse_problem_template
class TestCaseUploadForm(forms.Form): class TestCaseUploadForm(forms.Form):
@ -110,9 +111,18 @@ class ContestProblemAdminSerializer(BaseProblemSerializer):
class ProblemSerializer(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: class Meta:
model = Problem 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): class ContestProblemSerializer(BaseProblemSerializer):
@ -131,3 +141,54 @@ class ContestProblemSafeSerializer(BaseProblemSerializer):
class ContestProblemMakePublicSerializer(serializers.Serializer): class ContestProblemMakePublicSerializer(serializers.Serializer):
id = serializers.IntegerField() id = serializers.IntegerField()
display_id = serializers.CharField(max_length=32) 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 ProblemTag
from .models import Problem, ProblemRuleType from .models import Problem, ProblemRuleType
from .views.admin import TestCaseAPI
from contest.models import Contest from contest.models import Contest
from contest.tests import DEFAULT_CONTEST_DATA 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", 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", "output_description": "test", "time_limit": 1000, "memory_limit": 256, "difficulty": "Low",
"visible": True, "tags": ["test"], "languages": ["C", "C++", "Java", "Python2"], "template": {}, "visible": True, "tags": ["test"], "languages": ["C", "C++", "Java", "Python2"], "template": {},
@ -257,3 +260,44 @@ class ContestProblemTest(ProblemCreateTestBase):
contest.save() contest.save()
resp = self.client.get(self.url + "?contest_id=" + str(self.contest["id"])) resp = self.client.get(self.url + "?contest_id=" + str(self.contest["id"]))
self.assertSuccess(resp) 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 ""}