@xcpcio/core 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/rank.ts CHANGED
@@ -7,6 +7,7 @@ import type { Submissions } from "./submission";
7
7
  import { Submission } from "./submission";
8
8
  import { TeamProblemStatistics } from "./problem";
9
9
  import { RankStatistics } from "./rank-statistics";
10
+ import { Balloon, type Balloons } from "./balloon";
10
11
 
11
12
  export interface SelectOptionItem {
12
13
  value: string;
@@ -126,6 +127,8 @@ export class Rank {
126
127
 
127
128
  options: RankOptions;
128
129
 
130
+ balloons: Balloons;
131
+
129
132
  constructor(contest: Contest, teams: Teams, submissions: Submissions) {
130
133
  this.contest = contest;
131
134
 
@@ -142,40 +145,46 @@ export class Rank {
142
145
  this.rankStatistics = new RankStatistics();
143
146
 
144
147
  this.options = new RankOptions();
148
+
149
+ this.balloons = [];
145
150
  }
146
151
 
147
- buildRank() {
152
+ cleanRank() {
148
153
  (() => {
149
- (() => {
150
- this.teams = [];
151
-
152
- for (const [_k, v] of this.teamsMap) {
153
- if (this.filterTeamByOrg(v)) {
154
- continue;
155
- }
154
+ this.teams = [];
156
155
 
157
- this.teams.push(v);
156
+ for (const [_k, v] of this.teamsMap) {
157
+ if (this.filterTeamByOrg(v)) {
158
+ continue;
158
159
  }
159
- })();
160
-
161
- for (const t of this.teams) {
162
- t.reset();
163
160
 
164
- t.problemStatistics = this.contest.problems.map((p) => {
165
- const ps = new TeamProblemStatistics();
166
- ps.problem = p;
167
- ps.contestPenalty = this.contest.penalty;
161
+ this.teams.push(v);
162
+ }
163
+ })();
168
164
 
169
- return ps;
170
- });
165
+ for (const t of this.teams) {
166
+ t.reset();
171
167
 
172
- t.problemStatisticsMap = new Map(t.problemStatistics.map(ps => [ps.problem.id, ps]));
173
- }
168
+ t.problemStatistics = this.contest.problems.map((p) => {
169
+ const ps = new TeamProblemStatistics();
170
+ ps.problem = p;
171
+ ps.contestPenalty = this.contest.penalty;
174
172
 
175
- this.contest.problems.forEach((p) => {
176
- p.statistics.reset();
173
+ return ps;
177
174
  });
178
175
 
176
+ t.problemStatisticsMap = new Map(t.problemStatistics.map(ps => [ps.problem.id, ps]));
177
+ }
178
+
179
+ this.contest.problems.forEach((p) => {
180
+ p.statistics.reset();
181
+ });
182
+ }
183
+
184
+ buildRank() {
185
+ (() => {
186
+ this.cleanRank();
187
+
179
188
  this.teams.forEach(t =>
180
189
  t.placeChartPoints.push({
181
190
  timePoint: 0,
@@ -187,6 +196,7 @@ export class Rank {
187
196
  (() => {
188
197
  this.rankStatistics.reset();
189
198
  this.rankStatistics.teamSolvedNum = Array(this.contest.problems.length + 1).fill(0);
199
+ this.rankStatistics.teamSolvedNumIndex = Array(this.contest.problems.length + 1).fill(0);
190
200
  })();
191
201
 
192
202
  let preSubmissionTimestampToMinute = 0;
@@ -295,6 +305,17 @@ export class Rank {
295
305
  this.rankStatistics.teamSolvedNum[t.solvedProblemNum]++;
296
306
  }
297
307
 
308
+ {
309
+ let current = 0;
310
+ const teamSolvedNum = this.rankStatistics.teamSolvedNum;
311
+ const teamSolvedNumIndex = this.rankStatistics.teamSolvedNumIndex;
312
+
313
+ for (let i = teamSolvedNumIndex.length - 1; i >= 0; i--) {
314
+ current += (teamSolvedNum[i] > 0 ? 1 : 0);
315
+ teamSolvedNumIndex[i] = current;
316
+ }
317
+ }
318
+
298
319
  if (this.teams.length > 0) {
299
320
  this.rankStatistics.maxSolvedProblems = this.teams[0].solvedProblemNum;
300
321
  }
@@ -394,4 +415,44 @@ export class Rank {
394
415
  s.timestamp <= this.options.timestamp,
395
416
  ).sort(Submission.compare);
396
417
  }
418
+
419
+ buildBalloons() {
420
+ this.balloons = [];
421
+ this.cleanRank();
422
+
423
+ const allSubmissions = this.getSubmissions();
424
+
425
+ for (let ix = 0; ix < allSubmissions.length; ix++) {
426
+ const s = allSubmissions[ix];
427
+
428
+ const teamId = s.teamId;
429
+ const problemId = s.problemId;
430
+ const team = this.teamsMap.get(teamId);
431
+ const problem = this.contest.problemsMap.get(problemId);
432
+
433
+ (() => {
434
+ if (team === undefined || problem === undefined) {
435
+ return;
436
+ }
437
+
438
+ const problemStatistics = team.problemStatisticsMap.get(problemId) as TeamProblemStatistics;
439
+
440
+ if (problemStatistics.isSolved) {
441
+ return;
442
+ }
443
+
444
+ if (s.isAccepted()) {
445
+ problemStatistics.isSolved = true;
446
+ problemStatistics.solvedTimestamp = s.timestamp;
447
+
448
+ const b = new Balloon();
449
+ b.team = team;
450
+ b.problem = problem;
451
+ b.submission = s;
452
+
453
+ this.balloons.push(b);
454
+ }
455
+ })();
456
+ }
457
+ }
397
458
  }