Add contest freeze
This commit is contained in:
parent
2c39774ff7
commit
a35ea0f6d5
13 changed files with 338 additions and 215 deletions
|
@ -12,6 +12,7 @@ from judge.contest_format.default import DefaultContestFormat
|
|||
from judge.contest_format.registry import register_contest_format
|
||||
from judge.timezone import from_database_time
|
||||
from judge.utils.timedelta import nice_repr
|
||||
from django.db.models import Min, OuterRef, Subquery
|
||||
|
||||
|
||||
@register_contest_format("ioi")
|
||||
|
@ -45,41 +46,42 @@ class IOIContestFormat(DefaultContestFormat):
|
|||
|
||||
def update_participation(self, participation):
|
||||
cumtime = 0
|
||||
points = 0
|
||||
score = 0
|
||||
format_data = {}
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT MAX(cs.points) as `score`, (
|
||||
SELECT MIN(csub.date)
|
||||
FROM judge_contestsubmission ccs LEFT OUTER JOIN
|
||||
judge_submission csub ON (csub.id = ccs.submission_id)
|
||||
WHERE ccs.problem_id = cp.id AND ccs.participation_id = %s AND ccs.points = MAX(cs.points)
|
||||
) AS `time`, cp.id AS `prob`
|
||||
FROM judge_contestproblem cp INNER JOIN
|
||||
judge_contestsubmission cs ON (cs.problem_id = cp.id AND cs.participation_id = %s) LEFT OUTER JOIN
|
||||
judge_submission sub ON (sub.id = cs.submission_id)
|
||||
GROUP BY cp.id
|
||||
""",
|
||||
(participation.id, participation.id),
|
||||
queryset = participation.submissions
|
||||
if self.contest.freeze_after:
|
||||
queryset = queryset.filter(
|
||||
submission__date__lt=participation.start + self.contest.freeze_after
|
||||
)
|
||||
|
||||
for score, time, prob in cursor.fetchall():
|
||||
if self.config["cumtime"]:
|
||||
dt = (
|
||||
from_database_time(time) - participation.start
|
||||
).total_seconds()
|
||||
if score:
|
||||
cumtime += dt
|
||||
else:
|
||||
dt = 0
|
||||
queryset = (
|
||||
queryset.values("problem_id")
|
||||
.filter(
|
||||
points=Subquery(
|
||||
queryset.filter(problem_id=OuterRef("problem_id"))
|
||||
.order_by("-points")
|
||||
.values("points")[:1]
|
||||
)
|
||||
)
|
||||
.annotate(time=Min("submission__date"))
|
||||
.values_list("problem_id", "time", "points")
|
||||
)
|
||||
|
||||
format_data[str(prob)] = {"time": dt, "points": score}
|
||||
points += score
|
||||
for problem_id, time, points in queryset:
|
||||
if self.config["cumtime"]:
|
||||
dt = (time - participation.start).total_seconds()
|
||||
if points:
|
||||
cumtime += dt
|
||||
else:
|
||||
dt = 0
|
||||
|
||||
format_data[str(problem_id)] = {"points": points, "time": dt}
|
||||
score += points
|
||||
|
||||
self.handle_frozen_state(participation, format_data)
|
||||
participation.cumtime = max(cumtime, 0)
|
||||
participation.score = points
|
||||
participation.score = score
|
||||
participation.tiebreaker = 0
|
||||
participation.format_data = format_data
|
||||
participation.save()
|
||||
|
@ -99,6 +101,7 @@ class IOIContestFormat(DefaultContestFormat):
|
|||
+ self.best_solution_state(
|
||||
format_data["points"], contest_problem.points
|
||||
)
|
||||
+ (" frozen" if format_data.get("frozen") else "")
|
||||
),
|
||||
url=reverse(
|
||||
"contest_user_submissions_ajax",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue