Add final ranking for superuser (ioi16 only)

This commit is contained in:
cuom1999 2022-12-28 14:38:32 -06:00
parent 6635c3ee99
commit 309b6298e2
16 changed files with 424 additions and 336 deletions

View file

@ -112,7 +112,7 @@ class AtCoderContestFormat(DefaultContestFormat):
participation.format_data = format_data
participation.save()
def display_user_problem(self, participation, contest_problem):
def display_user_problem(self, participation, contest_problem, show_final=False):
format_data = (participation.format_data or {}).get(str(contest_problem.id))
if format_data:
penalty = (

View file

@ -48,7 +48,7 @@ class BaseContestFormat(metaclass=ABCMeta):
raise NotImplementedError()
@abstractmethod
def display_user_problem(self, participation, contest_problem):
def display_user_problem(self, participation, contest_problem, show_final):
"""
Returns the HTML fragment to show a user's performance on an individual problem. This is expected to use
information from the format_data field instead of computing it from scratch.
@ -60,7 +60,7 @@ class BaseContestFormat(metaclass=ABCMeta):
raise NotImplementedError()
@abstractmethod
def display_participation_result(self, participation):
def display_participation_result(self, participation, show_final):
"""
Returns the HTML fragment to show a user's performance on the whole contest. This is expected to use
information from the format_data field instead of computing it from scratch.

View file

@ -61,7 +61,7 @@ class DefaultContestFormat(BaseContestFormat):
participation.format_data = format_data
participation.save()
def display_user_problem(self, participation, contest_problem):
def display_user_problem(self, participation, contest_problem, show_final=False):
format_data = (participation.format_data or {}).get(str(contest_problem.id))
if format_data:
return format_html(
@ -94,7 +94,7 @@ class DefaultContestFormat(BaseContestFormat):
else:
return mark_safe('<td class="problem-score-col"></td>')
def display_participation_result(self, participation):
def display_participation_result(self, participation, show_final=False):
return format_html(
'<td class="user-points">{points}<div class="solving-time">{cumtime}</div></td>',
points=floatformat(participation.score, -self.contest.points_precision),

View file

@ -122,7 +122,7 @@ class ECOOContestFormat(DefaultContestFormat):
participation.format_data = format_data
participation.save()
def display_user_problem(self, participation, contest_problem):
def display_user_problem(self, participation, contest_problem, show_final=False):
format_data = (participation.format_data or {}).get(str(contest_problem.id))
if format_data:
bonus = (
@ -162,7 +162,7 @@ class ECOOContestFormat(DefaultContestFormat):
else:
return mark_safe("<td></td>")
def display_participation_result(self, participation):
def display_participation_result(self, participation, show_final=False):
return format_html(
'<td class="user-points">{points}<div class="solving-time">{cumtime}</div></td>',
points=floatformat(participation.score),

View file

@ -114,7 +114,7 @@ class ICPCContestFormat(DefaultContestFormat):
participation.format_data = format_data
participation.save()
def display_user_problem(self, participation, contest_problem):
def display_user_problem(self, participation, contest_problem, show_final=False):
format_data = (participation.format_data or {}).get(str(contest_problem.id))
if format_data:
penalty = (

View file

@ -86,8 +86,13 @@ class IOIContestFormat(DefaultContestFormat):
participation.format_data = format_data
participation.save()
def display_user_problem(self, participation, contest_problem):
format_data = (participation.format_data or {}).get(str(contest_problem.id))
def display_user_problem(self, participation, contest_problem, show_final=False):
if show_final:
format_data = (participation.format_data_final or {}).get(
str(contest_problem.id)
)
else:
format_data = (participation.format_data or {}).get(str(contest_problem.id))
if format_data:
return format_html(
'<td class="{state} problem-score-col"><a data-featherlight="{url}" href="#">{points}<div class="solving-time">{time}</div></a></td>',
@ -121,11 +126,17 @@ class IOIContestFormat(DefaultContestFormat):
else:
return mark_safe('<td class="problem-score-col"></td>')
def display_participation_result(self, participation):
def display_participation_result(self, participation, show_final=False):
if show_final:
score = participation.score_final
cumtime = participation.cumtime_final
else:
score = participation.score
cumtime = participation.cumtime
return format_html(
'<td class="user-points">{points}<div class="solving-time">{cumtime}</div></td>',
points=floatformat(participation.score, -self.contest.points_precision),
cumtime=nice_repr(timedelta(seconds=participation.cumtime), "noday")
points=floatformat(score, -self.contest.points_precision),
cumtime=nice_repr(timedelta(seconds=cumtime), "noday")
if self.config["cumtime"]
else "",
)

View file

@ -100,51 +100,73 @@ class NewIOIContestFormat(IOIContestFormat):
return cursor.fetchall()
def update_participation(self, participation):
cumtime = 0
score = 0
format_data = {}
frozen_subtasks = self.get_frozen_subtasks()
for (
problem_id,
problem_points,
time,
subtask_points,
total_subtask_points,
subtask,
sub_id,
) in self.get_results_by_subtask(participation):
problem_id = str(problem_id)
time = from_database_time(time)
if self.config["cumtime"]:
dt = (time - participation.start).total_seconds()
else:
dt = 0
def calculate_format_data(participation, include_frozen):
format_data = {}
for (
problem_id,
problem_points,
time,
subtask_points,
total_subtask_points,
subtask,
sub_id,
) in self.get_results_by_subtask(participation, include_frozen):
problem_id = str(problem_id)
time = from_database_time(time)
if self.config["cumtime"]:
dt = (time - participation.start).total_seconds()
else:
dt = 0
if format_data.get(problem_id) is None:
format_data[problem_id] = {"points": 0, "time": 0, "total_points": 0}
if subtask not in frozen_subtasks.get(problem_id, set()):
format_data[problem_id]["points"] += subtask_points
format_data[problem_id]["total_points"] += total_subtask_points
format_data[problem_id]["time"] = max(dt, format_data[problem_id]["time"])
format_data[problem_id]["problem_points"] = problem_points
if format_data.get(problem_id) is None:
format_data[problem_id] = {
"points": 0,
"time": 0,
"total_points": 0,
}
if (
subtask not in frozen_subtasks.get(problem_id, set())
or include_frozen
):
format_data[problem_id]["points"] += subtask_points
format_data[problem_id]["total_points"] += total_subtask_points
format_data[problem_id]["time"] = max(
dt, format_data[problem_id]["time"]
)
format_data[problem_id]["problem_points"] = problem_points
for problem_data in format_data.values():
if not problem_data["total_points"]:
continue
penalty = problem_data["time"]
problem_data["points"] = (
problem_data["points"]
/ problem_data["total_points"]
* problem_data["problem_points"]
)
if self.config["cumtime"] and problem_data["points"]:
cumtime += penalty
score += problem_data["points"]
return format_data
def recalculate_results(format_data):
cumtime = 0
score = 0
for problem_data in format_data.values():
if not problem_data["total_points"]:
continue
penalty = problem_data["time"]
problem_data["points"] = (
problem_data["points"]
/ problem_data["total_points"]
* problem_data["problem_points"]
)
if self.config["cumtime"] and problem_data["points"]:
cumtime += penalty
score += problem_data["points"]
return score, cumtime
format_data = calculate_format_data(participation, False)
score, cumtime = recalculate_results(format_data)
self.handle_frozen_state(participation, format_data)
participation.cumtime = max(cumtime, 0)
participation.score = round(score, self.contest.points_precision)
participation.tiebreaker = 0
participation.format_data = format_data
format_data_final = calculate_format_data(participation, True)
score_final, cumtime_final = recalculate_results(format_data_final)
participation.cumtime_final = max(cumtime_final, 0)
participation.score_final = round(score_final, self.contest.points_precision)
participation.format_data_final = format_data_final
participation.save()