@xcpcio/core 0.39.0 → 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 +39 -14
- package/dist/index.d.ts +4 -1
- package/dist/index.mjs +39 -14
- package/package.json +2 -2
- package/src/rank-statistics.ts +6 -0
- package/src/rank.ts +14 -10
- package/src/team.ts +34 -7
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
|
-
|
|
1397
|
+
{
|
|
1378
1398
|
const o = this.contest.options;
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
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
|
-
|
|
1366
|
+
{
|
|
1347
1367
|
const o = this.contest.options;
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
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.
|
|
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.
|
|
49
|
+
"@xcpcio/types": "0.40.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@babel/types": "^7.22.4",
|
package/src/rank-statistics.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
o.submissionHasTimeField = true;
|
|
157
|
-
}
|
|
156
|
+
if (s.time) {
|
|
157
|
+
o.submissionHasTimeField = true;
|
|
158
|
+
}
|
|
158
159
|
|
|
159
|
-
|
|
160
|
-
|
|
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;
|