@xcpcio/core 0.39.1 → 0.40.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/dist/index.cjs CHANGED
@@ -666,6 +666,7 @@ class Team {
666
666
  this.submissions = [];
667
667
  this.placeChartPoints = [];
668
668
  this.awards = [];
669
+ this.se = 0;
669
670
  }
670
671
  reset() {
671
672
  this.rank = 0;
@@ -681,15 +682,11 @@ class Team {
681
682
  this.submissions = [];
682
683
  this.placeChartPoints = [];
683
684
  this.awards = [];
685
+ this.se = 0;
684
686
  }
685
687
  get penaltyToMinute() {
686
688
  return Math.floor(this.penalty / 60);
687
689
  }
688
- get dirt() {
689
- const attemptedNum = this.attemptedProblemNum;
690
- const solvedNum = this.solvedProblemNum;
691
- return calcDirt(attemptedNum, solvedNum);
692
- }
693
690
  get isUnofficial() {
694
691
  return this.group.includes("unofficial");
695
692
  }
@@ -719,6 +716,27 @@ class Team {
719
716
  get isEffectiveTeam() {
720
717
  return this.solvedProblemNum > 0;
721
718
  }
719
+ get dirt() {
720
+ const attemptedNum = this.attemptedProblemNum;
721
+ const solvedNum = this.solvedProblemNum;
722
+ return calcDirt(attemptedNum, solvedNum);
723
+ }
724
+ calcSE(totalTeams) {
725
+ let acceptedProblemNums = 0;
726
+ let total = 0;
727
+ this.problemStatistics.forEach((p) => {
728
+ if (p.isSolved) {
729
+ acceptedProblemNums += 1;
730
+ total += p.problem.statistics.acceptedNum;
731
+ }
732
+ });
733
+ if (totalTeams === 0 || acceptedProblemNums === 0) {
734
+ return 0;
735
+ }
736
+ const res = (acceptedProblemNums * totalTeams - total) / totalTeams / acceptedProblemNums;
737
+ this.se = Math.round(res * 100) / 100;
738
+ return this.se;
739
+ }
722
740
  calcSolvedData(options) {
723
741
  this.solvedProblemNum = 0;
724
742
  this.attemptedProblemNum = 0;
@@ -1289,12 +1307,14 @@ class RankStatistics {
1289
1307
  this.teamSolvedNumIndex = [];
1290
1308
  this.maxSolvedProblems = 0;
1291
1309
  this.effectiveTeamNum = 0;
1310
+ this.totalTeamNum = 0;
1292
1311
  }
1293
1312
  reset() {
1294
1313
  this.teamSolvedNum = [];
1295
1314
  this.teamSolvedNumIndex = [];
1296
1315
  this.maxSolvedProblems = 0;
1297
1316
  this.effectiveTeamNum = 0;
1317
+ this.totalTeamNum = 0;
1298
1318
  }
1299
1319
  getTeamSolvedNumIndex(solvedNum) {
1300
1320
  return this.teamSolvedNumIndex[solvedNum] ?? 0;
@@ -1374,16 +1394,19 @@ class Rank {
1374
1394
  this.teams = ___default.cloneDeep(teams);
1375
1395
  this.teamsMap = new Map(this.teams.map((t) => [t.id, t]));
1376
1396
  this.submissions = ___default.cloneDeep(submissions).sort(Submission.compare);
1377
- this.submissions.forEach((s) => {
1397
+ {
1378
1398
  const o = this.contest.options;
1379
- s.timestampUnit = o.submissionTimestampUnit;
1380
- if (s.time) {
1381
- o.submissionHasTimeField = true;
1382
- }
1383
- if (s.language) {
1384
- o.submissionHasLanguageField = true;
1385
- }
1386
- });
1399
+ const timestampUnit = ___default.cloneDeep(o.submissionTimestampUnit);
1400
+ this.submissions.forEach((s) => {
1401
+ s.timestampUnit = timestampUnit;
1402
+ if (s.time) {
1403
+ o.submissionHasTimeField = true;
1404
+ }
1405
+ if (s.language) {
1406
+ o.submissionHasLanguageField = true;
1407
+ }
1408
+ });
1409
+ }
1387
1410
  this.submissionsMap = new Map(this.submissions.map((s) => [s.id, s]));
1388
1411
  this.organizations = this.buildOrganizations();
1389
1412
  this.originTeams = this.teams.map((t) => t);
@@ -1525,6 +1548,8 @@ class Rank {
1525
1548
  this.buildTeamRank();
1526
1549
  this.buildOrgRank();
1527
1550
  this.rankStatistics.effectiveTeamNum = this.teams.filter((t) => t.isEffectiveTeam).length;
1551
+ this.rankStatistics.totalTeamNum = this.teams.length;
1552
+ this.teams.forEach((t) => t.calcSE(this.rankStatistics.totalTeamNum));
1528
1553
  this.buildAwards();
1529
1554
  this.teams.forEach((t) => t.calcAwards(this.contest.awards?.get(this.options.group)));
1530
1555
  this.teams.forEach((t) => t.postProcessPlaceChartPoints());
package/dist/index.d.ts CHANGED
@@ -195,15 +195,17 @@ declare class Team {
195
195
  placeChartPoints: Array<PlaceChartPointData>;
196
196
  awards: MedalType[];
197
197
  location?: string;
198
+ se: number;
198
199
  constructor();
199
200
  reset(): void;
200
201
  get penaltyToMinute(): number;
201
- get dirt(): number;
202
202
  get isUnofficial(): boolean;
203
203
  get isGirl(): boolean;
204
204
  get membersToArray(): string[];
205
205
  get membersToString(): string | undefined;
206
206
  get isEffectiveTeam(): boolean;
207
+ get dirt(): number;
208
+ calcSE(totalTeams: number): number;
207
209
  calcSolvedData(options: ContestOptions): void;
208
210
  calcAwards(awards?: Award[]): void;
209
211
  isEqualRank(otherTeam: Team): boolean;
@@ -219,6 +221,7 @@ declare class RankStatistics {
219
221
  teamSolvedNumIndex: Array<number>;
220
222
  maxSolvedProblems: number;
221
223
  effectiveTeamNum: number;
224
+ totalTeamNum: number;
222
225
  constructor();
223
226
  reset(): void;
224
227
  getTeamSolvedNumIndex(solvedNum: number): number;
package/dist/index.mjs CHANGED
@@ -635,6 +635,7 @@ class Team {
635
635
  this.submissions = [];
636
636
  this.placeChartPoints = [];
637
637
  this.awards = [];
638
+ this.se = 0;
638
639
  }
639
640
  reset() {
640
641
  this.rank = 0;
@@ -650,15 +651,11 @@ class Team {
650
651
  this.submissions = [];
651
652
  this.placeChartPoints = [];
652
653
  this.awards = [];
654
+ this.se = 0;
653
655
  }
654
656
  get penaltyToMinute() {
655
657
  return Math.floor(this.penalty / 60);
656
658
  }
657
- get dirt() {
658
- const attemptedNum = this.attemptedProblemNum;
659
- const solvedNum = this.solvedProblemNum;
660
- return calcDirt(attemptedNum, solvedNum);
661
- }
662
659
  get isUnofficial() {
663
660
  return this.group.includes("unofficial");
664
661
  }
@@ -688,6 +685,27 @@ class Team {
688
685
  get isEffectiveTeam() {
689
686
  return this.solvedProblemNum > 0;
690
687
  }
688
+ get dirt() {
689
+ const attemptedNum = this.attemptedProblemNum;
690
+ const solvedNum = this.solvedProblemNum;
691
+ return calcDirt(attemptedNum, solvedNum);
692
+ }
693
+ calcSE(totalTeams) {
694
+ let acceptedProblemNums = 0;
695
+ let total = 0;
696
+ this.problemStatistics.forEach((p) => {
697
+ if (p.isSolved) {
698
+ acceptedProblemNums += 1;
699
+ total += p.problem.statistics.acceptedNum;
700
+ }
701
+ });
702
+ if (totalTeams === 0 || acceptedProblemNums === 0) {
703
+ return 0;
704
+ }
705
+ const res = (acceptedProblemNums * totalTeams - total) / totalTeams / acceptedProblemNums;
706
+ this.se = Math.round(res * 100) / 100;
707
+ return this.se;
708
+ }
691
709
  calcSolvedData(options) {
692
710
  this.solvedProblemNum = 0;
693
711
  this.attemptedProblemNum = 0;
@@ -1258,12 +1276,14 @@ class RankStatistics {
1258
1276
  this.teamSolvedNumIndex = [];
1259
1277
  this.maxSolvedProblems = 0;
1260
1278
  this.effectiveTeamNum = 0;
1279
+ this.totalTeamNum = 0;
1261
1280
  }
1262
1281
  reset() {
1263
1282
  this.teamSolvedNum = [];
1264
1283
  this.teamSolvedNumIndex = [];
1265
1284
  this.maxSolvedProblems = 0;
1266
1285
  this.effectiveTeamNum = 0;
1286
+ this.totalTeamNum = 0;
1267
1287
  }
1268
1288
  getTeamSolvedNumIndex(solvedNum) {
1269
1289
  return this.teamSolvedNumIndex[solvedNum] ?? 0;
@@ -1343,16 +1363,19 @@ class Rank {
1343
1363
  this.teams = _.cloneDeep(teams);
1344
1364
  this.teamsMap = new Map(this.teams.map((t) => [t.id, t]));
1345
1365
  this.submissions = _.cloneDeep(submissions).sort(Submission.compare);
1346
- this.submissions.forEach((s) => {
1366
+ {
1347
1367
  const o = this.contest.options;
1348
- s.timestampUnit = o.submissionTimestampUnit;
1349
- if (s.time) {
1350
- o.submissionHasTimeField = true;
1351
- }
1352
- if (s.language) {
1353
- o.submissionHasLanguageField = true;
1354
- }
1355
- });
1368
+ const timestampUnit = _.cloneDeep(o.submissionTimestampUnit);
1369
+ this.submissions.forEach((s) => {
1370
+ s.timestampUnit = timestampUnit;
1371
+ if (s.time) {
1372
+ o.submissionHasTimeField = true;
1373
+ }
1374
+ if (s.language) {
1375
+ o.submissionHasLanguageField = true;
1376
+ }
1377
+ });
1378
+ }
1356
1379
  this.submissionsMap = new Map(this.submissions.map((s) => [s.id, s]));
1357
1380
  this.organizations = this.buildOrganizations();
1358
1381
  this.originTeams = this.teams.map((t) => t);
@@ -1494,6 +1517,8 @@ class Rank {
1494
1517
  this.buildTeamRank();
1495
1518
  this.buildOrgRank();
1496
1519
  this.rankStatistics.effectiveTeamNum = this.teams.filter((t) => t.isEffectiveTeam).length;
1520
+ this.rankStatistics.totalTeamNum = this.teams.length;
1521
+ this.teams.forEach((t) => t.calcSE(this.rankStatistics.totalTeamNum));
1497
1522
  this.buildAwards();
1498
1523
  this.teams.forEach((t) => t.calcAwards(this.contest.awards?.get(this.options.group)));
1499
1524
  this.teams.forEach((t) => t.postProcessPlaceChartPoints());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xcpcio/core",
3
- "version": "0.39.1",
3
+ "version": "0.40.0",
4
4
  "description": "XCPCIO Core",
5
5
  "author": "Dup4 <lyuzhi.pan@gmail.com>",
6
6
  "license": "MIT",
@@ -46,7 +46,7 @@
46
46
  "lodash": "^4.17.21",
47
47
  "string-width": "^6.1.0",
48
48
  "xlsx-js-style": "^1.2.0",
49
- "@xcpcio/types": "0.39.1"
49
+ "@xcpcio/types": "0.40.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@babel/types": "^7.22.4",
@@ -5,12 +5,16 @@ export class RankStatistics {
5
5
 
6
6
  effectiveTeamNum: number;
7
7
 
8
+ totalTeamNum: number;
9
+
8
10
  constructor() {
9
11
  this.teamSolvedNum = [];
10
12
  this.teamSolvedNumIndex = [];
11
13
  this.maxSolvedProblems = 0;
12
14
 
13
15
  this.effectiveTeamNum = 0;
16
+
17
+ this.totalTeamNum = 0;
14
18
  }
15
19
 
16
20
  reset() {
@@ -19,6 +23,8 @@ export class RankStatistics {
19
23
  this.maxSolvedProblems = 0;
20
24
 
21
25
  this.effectiveTeamNum = 0;
26
+
27
+ this.totalTeamNum = 0;
22
28
  }
23
29
 
24
30
  getTeamSolvedNumIndex(solvedNum: number): number {
package/src/rank.ts CHANGED
@@ -147,19 +147,21 @@ export class Rank {
147
147
 
148
148
  this.submissions = _.cloneDeep(submissions).sort(Submission.compare);
149
149
 
150
- this.submissions.forEach((s) => {
150
+ {
151
151
  const o = this.contest.options;
152
+ const timestampUnit = _.cloneDeep(o.submissionTimestampUnit);
153
+ this.submissions.forEach((s) => {
154
+ s.timestampUnit = timestampUnit;
152
155
 
153
- s.timestampUnit = o.submissionTimestampUnit;
154
-
155
- if (s.time) {
156
- o.submissionHasTimeField = true;
157
- }
156
+ if (s.time) {
157
+ o.submissionHasTimeField = true;
158
+ }
158
159
 
159
- if (s.language) {
160
- o.submissionHasLanguageField = true;
161
- }
162
- });
160
+ if (s.language) {
161
+ o.submissionHasLanguageField = true;
162
+ }
163
+ });
164
+ }
163
165
 
164
166
  this.submissionsMap = new Map(this.submissions.map(s => [s.id, s]));
165
167
 
@@ -349,6 +351,8 @@ export class Rank {
349
351
  this.buildOrgRank();
350
352
 
351
353
  this.rankStatistics.effectiveTeamNum = this.teams.filter(t => t.isEffectiveTeam).length;
354
+ this.rankStatistics.totalTeamNum = this.teams.length;
355
+ this.teams.forEach(t => t.calcSE(this.rankStatistics.totalTeamNum));
352
356
  this.buildAwards();
353
357
 
354
358
  this.teams.forEach(t => t.calcAwards(this.contest.awards?.get(this.options.group)));
package/src/team.ts CHANGED
@@ -54,6 +54,8 @@ export class Team {
54
54
 
55
55
  location?: string;
56
56
 
57
+ se: number;
58
+
57
59
  constructor() {
58
60
  this.id = "";
59
61
  this.name = "";
@@ -83,6 +85,8 @@ export class Team {
83
85
  this.placeChartPoints = [];
84
86
 
85
87
  this.awards = [];
88
+
89
+ this.se = 0;
86
90
  }
87
91
 
88
92
  reset() {
@@ -106,19 +110,14 @@ export class Team {
106
110
  this.placeChartPoints = [];
107
111
 
108
112
  this.awards = [];
113
+
114
+ this.se = 0;
109
115
  }
110
116
 
111
117
  get penaltyToMinute() {
112
118
  return Math.floor(this.penalty / 60);
113
119
  }
114
120
 
115
- get dirt() {
116
- const attemptedNum = this.attemptedProblemNum;
117
- const solvedNum = this.solvedProblemNum;
118
-
119
- return calcDirt(attemptedNum, solvedNum);
120
- }
121
-
122
121
  get isUnofficial() {
123
122
  return this.group.includes("unofficial");
124
123
  }
@@ -157,6 +156,34 @@ export class Team {
157
156
  return this.solvedProblemNum > 0;
158
157
  }
159
158
 
159
+ get dirt() {
160
+ const attemptedNum = this.attemptedProblemNum;
161
+ const solvedNum = this.solvedProblemNum;
162
+
163
+ return calcDirt(attemptedNum, solvedNum);
164
+ }
165
+
166
+ calcSE(totalTeams: number) {
167
+ let acceptedProblemNums = 0;
168
+ let total = 0;
169
+
170
+ this.problemStatistics.forEach((p) => {
171
+ if (p.isSolved) {
172
+ acceptedProblemNums += 1;
173
+ total += p.problem.statistics.acceptedNum;
174
+ }
175
+ });
176
+
177
+ if (totalTeams === 0 || acceptedProblemNums === 0) {
178
+ return 0;
179
+ }
180
+
181
+ const res = (acceptedProblemNums * totalTeams - total) / totalTeams / acceptedProblemNums;
182
+ this.se = Math.round(res * 100) / 100;
183
+
184
+ return this.se;
185
+ }
186
+
160
187
  calcSolvedData(options: ContestOptions) {
161
188
  this.solvedProblemNum = 0;
162
189
  this.attemptedProblemNum = 0;