@xcpcio/core 0.12.0 → 0.14.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 +371 -223
- package/dist/index.d.ts +52 -38
- package/dist/index.mjs +356 -223
- package/package.json +4 -2
- package/src/export/cf.ts +120 -0
- package/src/export/general-excel.ts +153 -0
- package/src/export/index.ts +2 -0
- package/src/index.ts +1 -1
- package/src/problem.ts +8 -0
- package/src/export.ts +0 -116
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SubmissionStatus, ContestState } from '@xcpcio/types';
|
|
1
2
|
import dayjs from 'dayjs';
|
|
2
3
|
export { default as dayjs } from 'dayjs';
|
|
3
4
|
import duration from 'dayjs/plugin/duration';
|
|
@@ -8,30 +9,125 @@ import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
|
|
|
8
9
|
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
|
|
9
10
|
import minMax from 'dayjs/plugin/minMax';
|
|
10
11
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
11
|
-
import { ContestState, SubmissionStatus } from '@xcpcio/types';
|
|
12
12
|
import _ from 'lodash';
|
|
13
|
+
import * as XLSX from 'xlsx-js-style';
|
|
14
|
+
import stringWidth from 'string-width';
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
MedalType2[MedalType2["BRONZE"] = 3] = "BRONZE";
|
|
19
|
-
MedalType2[MedalType2["HONORABLE"] = 4] = "HONORABLE";
|
|
20
|
-
return MedalType2;
|
|
21
|
-
})(MedalType || {});
|
|
22
|
-
class Award {
|
|
23
|
-
constructor() {
|
|
24
|
-
this.medalType = 0 /* UNKNOWN */;
|
|
25
|
-
this.minRank = 0;
|
|
26
|
-
this.maxRank = 0;
|
|
16
|
+
function stringToSubmissionStatus(status) {
|
|
17
|
+
status = status.toUpperCase().replace(" ", "_");
|
|
18
|
+
if (["OK", "AC", SubmissionStatus.ACCEPTED.toString()].includes(status)) {
|
|
19
|
+
return SubmissionStatus.ACCEPTED;
|
|
27
20
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
function calcDict(attemptedNum, solvedNum) {
|
|
31
|
-
if (solvedNum === 0) {
|
|
32
|
-
return 0;
|
|
21
|
+
if ([SubmissionStatus.CORRECT.toString()].includes(status)) {
|
|
22
|
+
return SubmissionStatus.ACCEPTED;
|
|
33
23
|
}
|
|
34
|
-
|
|
24
|
+
if ([SubmissionStatus.PARTIALLY_CORRECT.toString()].includes(status)) {
|
|
25
|
+
return SubmissionStatus.PARTIALLY_CORRECT;
|
|
26
|
+
}
|
|
27
|
+
if (["WA", SubmissionStatus.WRONG_ANSWER.toString()].includes(status)) {
|
|
28
|
+
return SubmissionStatus.WRONG_ANSWER;
|
|
29
|
+
}
|
|
30
|
+
if (["RJ", "INCORRECT", SubmissionStatus.REJECTED.toString()].includes(status)) {
|
|
31
|
+
return SubmissionStatus.REJECTED;
|
|
32
|
+
}
|
|
33
|
+
if (["PD", SubmissionStatus.PENDING.toString()].includes(status)) {
|
|
34
|
+
return SubmissionStatus.PENDING;
|
|
35
|
+
}
|
|
36
|
+
if ([SubmissionStatus.WAITING.toString()].includes(status)) {
|
|
37
|
+
return SubmissionStatus.WAITING;
|
|
38
|
+
}
|
|
39
|
+
if ([SubmissionStatus.JUDGING.toString()].includes(status)) {
|
|
40
|
+
return SubmissionStatus.JUDGING;
|
|
41
|
+
}
|
|
42
|
+
if ([SubmissionStatus.FROZEN.toString()].includes(status)) {
|
|
43
|
+
return SubmissionStatus.FROZEN;
|
|
44
|
+
}
|
|
45
|
+
if (["CE", SubmissionStatus.COMPILATION_ERROR.toString()].includes(status)) {
|
|
46
|
+
return SubmissionStatus.COMPILATION_ERROR;
|
|
47
|
+
}
|
|
48
|
+
if (["PE", SubmissionStatus.PRESENTATION_ERROR.toString()].includes(status)) {
|
|
49
|
+
return SubmissionStatus.PRESENTATION_ERROR;
|
|
50
|
+
}
|
|
51
|
+
if (["TL", "TLE", SubmissionStatus.TIME_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
52
|
+
return SubmissionStatus.TIME_LIMIT_EXCEEDED;
|
|
53
|
+
}
|
|
54
|
+
if (["ML", "MLE", SubmissionStatus.MEMORY_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
55
|
+
return SubmissionStatus.MEMORY_LIMIT_EXCEEDED;
|
|
56
|
+
}
|
|
57
|
+
if (["OL", "OLE", SubmissionStatus.OUTPUT_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
58
|
+
return SubmissionStatus.OUTPUT_LIMIT_EXCEEDED;
|
|
59
|
+
}
|
|
60
|
+
if (["IL", "ILE", SubmissionStatus.IDLENESS_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
61
|
+
return SubmissionStatus.IDLENESS_LIMIT_EXCEEDED;
|
|
62
|
+
}
|
|
63
|
+
if (["RT", "RE", "RTE", SubmissionStatus.RUNTIME_ERROR.toString()].includes(status)) {
|
|
64
|
+
return SubmissionStatus.RUNTIME_ERROR;
|
|
65
|
+
}
|
|
66
|
+
if (["JE", SubmissionStatus.JUDGEMENT_FAILED.toString()].includes(status)) {
|
|
67
|
+
return SubmissionStatus.JUDGEMENT_FAILED;
|
|
68
|
+
}
|
|
69
|
+
if (["SE", SubmissionStatus.SYSTEM_ERROR.toString()].includes(status)) {
|
|
70
|
+
return SubmissionStatus.SYSTEM_ERROR;
|
|
71
|
+
}
|
|
72
|
+
if ([SubmissionStatus.HACKED.toString()].includes(status)) {
|
|
73
|
+
return SubmissionStatus.HACKED;
|
|
74
|
+
}
|
|
75
|
+
if ([SubmissionStatus.CONFIGURATION_ERROR.toString()].includes(status)) {
|
|
76
|
+
return SubmissionStatus.CONFIGURATION_ERROR;
|
|
77
|
+
}
|
|
78
|
+
if ([SubmissionStatus.CANCELED.toString()].includes(status)) {
|
|
79
|
+
return SubmissionStatus.CANCELED;
|
|
80
|
+
}
|
|
81
|
+
if ([SubmissionStatus.SKIPPED.toString()].includes(status)) {
|
|
82
|
+
return SubmissionStatus.SKIPPED;
|
|
83
|
+
}
|
|
84
|
+
if ([SubmissionStatus.SECURITY_VIOLATED.toString()].includes(status)) {
|
|
85
|
+
return SubmissionStatus.SECURITY_VIOLATED;
|
|
86
|
+
}
|
|
87
|
+
if ([SubmissionStatus.DENIAL_OF_JUDGEMENT.toString()].includes(status)) {
|
|
88
|
+
return SubmissionStatus.DENIAL_OF_JUDGEMENT;
|
|
89
|
+
}
|
|
90
|
+
return SubmissionStatus.UNKNOWN;
|
|
91
|
+
}
|
|
92
|
+
function isAccepted(status) {
|
|
93
|
+
const acceptedArray = [SubmissionStatus.ACCEPTED, SubmissionStatus.CORRECT];
|
|
94
|
+
return acceptedArray.includes(status);
|
|
95
|
+
}
|
|
96
|
+
function isRejected(status) {
|
|
97
|
+
const rejectArray = [
|
|
98
|
+
SubmissionStatus.RUNTIME_ERROR,
|
|
99
|
+
SubmissionStatus.TIME_LIMIT_EXCEEDED,
|
|
100
|
+
SubmissionStatus.MEMORY_LIMIT_EXCEEDED,
|
|
101
|
+
SubmissionStatus.OUTPUT_LIMIT_EXCEEDED,
|
|
102
|
+
SubmissionStatus.IDLENESS_LIMIT_EXCEEDED,
|
|
103
|
+
SubmissionStatus.WRONG_ANSWER,
|
|
104
|
+
SubmissionStatus.REJECTED,
|
|
105
|
+
SubmissionStatus.JUDGEMENT_FAILED,
|
|
106
|
+
SubmissionStatus.HACKED
|
|
107
|
+
];
|
|
108
|
+
return rejectArray.includes(status);
|
|
109
|
+
}
|
|
110
|
+
function isPending(status) {
|
|
111
|
+
const pendingArray = [
|
|
112
|
+
SubmissionStatus.PENDING,
|
|
113
|
+
SubmissionStatus.WAITING,
|
|
114
|
+
SubmissionStatus.JUDGING,
|
|
115
|
+
SubmissionStatus.FROZEN
|
|
116
|
+
];
|
|
117
|
+
return pendingArray.includes(status);
|
|
118
|
+
}
|
|
119
|
+
function isNotCalculatedPenaltyStatus(status) {
|
|
120
|
+
const isNotCalculatedPenaltyArray = [
|
|
121
|
+
SubmissionStatus.COMPILATION_ERROR,
|
|
122
|
+
SubmissionStatus.PRESENTATION_ERROR,
|
|
123
|
+
SubmissionStatus.CONFIGURATION_ERROR,
|
|
124
|
+
SubmissionStatus.SYSTEM_ERROR,
|
|
125
|
+
SubmissionStatus.CANCELED,
|
|
126
|
+
SubmissionStatus.SKIPPED,
|
|
127
|
+
SubmissionStatus.UNKNOWN,
|
|
128
|
+
SubmissionStatus.UNDEFINED
|
|
129
|
+
];
|
|
130
|
+
return isNotCalculatedPenaltyArray.includes(status);
|
|
35
131
|
}
|
|
36
132
|
|
|
37
133
|
dayjs.extend(duration);
|
|
@@ -70,6 +166,239 @@ function getTimeDiff(seconds) {
|
|
|
70
166
|
return [two(h), two(m), two(s)].join(":");
|
|
71
167
|
}
|
|
72
168
|
|
|
169
|
+
class CodeforcesGymGhostDATConverter {
|
|
170
|
+
constructor() {
|
|
171
|
+
}
|
|
172
|
+
convert(rank) {
|
|
173
|
+
let res = "";
|
|
174
|
+
res += `@contest "${rank.contest.name}"
|
|
175
|
+
@contlen ${Math.floor(dayjs.duration(rank.contest.endTime.diff(rank.contest.startTime)).asMinutes())}
|
|
176
|
+
@problems ${rank.contest.problems.length}
|
|
177
|
+
@teams ${rank.teams.length + 100}
|
|
178
|
+
@submissions ${rank.submissions.length}
|
|
179
|
+
`;
|
|
180
|
+
rank.contest.problems.forEach((p) => {
|
|
181
|
+
res += `@p ${p.label},${p.label},20,0
|
|
182
|
+
`;
|
|
183
|
+
});
|
|
184
|
+
let teamIndex = 1;
|
|
185
|
+
const teamIdMap = /* @__PURE__ */ new Map();
|
|
186
|
+
const submissionsIdMap = /* @__PURE__ */ new Map();
|
|
187
|
+
rank.teams.forEach((team) => {
|
|
188
|
+
let name = team.name;
|
|
189
|
+
if (team.organization) {
|
|
190
|
+
name = `${team.organization} - ${name}`;
|
|
191
|
+
}
|
|
192
|
+
if (team.members) {
|
|
193
|
+
name = `${name} - ${team.membersToString}`;
|
|
194
|
+
}
|
|
195
|
+
res += `@t ${teamIndex},0,1,${name}
|
|
196
|
+
`;
|
|
197
|
+
teamIdMap.set(team.id, teamIndex);
|
|
198
|
+
teamIndex++;
|
|
199
|
+
{
|
|
200
|
+
const mp = /* @__PURE__ */ new Map();
|
|
201
|
+
rank.contest.problems.forEach((p) => {
|
|
202
|
+
mp.set(p.id, 0);
|
|
203
|
+
});
|
|
204
|
+
submissionsIdMap.set(team.id, mp);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
for (let i = 0; i < 100; i++) {
|
|
208
|
+
res += `@t ${teamIndex},0,1,\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043A\u043E\u043C\u0430\u043D\u0434\u0443
|
|
209
|
+
`;
|
|
210
|
+
teamIndex++;
|
|
211
|
+
}
|
|
212
|
+
rank.getSubmissions().forEach((submission) => {
|
|
213
|
+
const teamId = submission.teamId;
|
|
214
|
+
const problemId = submission.problemId;
|
|
215
|
+
const problem = rank.contest.problemsMap.get(problemId);
|
|
216
|
+
if (!problem) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const status = this.submissionStatusToCodeforcesGymDatStatus(submission.status);
|
|
220
|
+
submissionsIdMap.get(teamId).set(problemId, submissionsIdMap.get(teamId).get(problemId) + 1);
|
|
221
|
+
res += `@s ${teamIdMap.get(teamId)},${problem.label},${submissionsIdMap.get(teamId)?.get(problemId)},${submission.timestamp},${status}
|
|
222
|
+
`;
|
|
223
|
+
});
|
|
224
|
+
return res;
|
|
225
|
+
}
|
|
226
|
+
submissionStatusToCodeforcesGymDatStatus(status) {
|
|
227
|
+
if (isAccepted(status)) {
|
|
228
|
+
return "OK";
|
|
229
|
+
}
|
|
230
|
+
if (status === SubmissionStatus.WRONG_ANSWER) {
|
|
231
|
+
return "WA";
|
|
232
|
+
}
|
|
233
|
+
if (status === SubmissionStatus.TIME_LIMIT_EXCEEDED) {
|
|
234
|
+
return "TL";
|
|
235
|
+
}
|
|
236
|
+
if (status === SubmissionStatus.MEMORY_LIMIT_EXCEEDED) {
|
|
237
|
+
return "ML";
|
|
238
|
+
}
|
|
239
|
+
if (status === SubmissionStatus.OUTPUT_LIMIT_EXCEEDED) {
|
|
240
|
+
return "IL";
|
|
241
|
+
}
|
|
242
|
+
if (status === SubmissionStatus.PRESENTATION_ERROR) {
|
|
243
|
+
return "PE";
|
|
244
|
+
}
|
|
245
|
+
if (status === SubmissionStatus.RUNTIME_ERROR) {
|
|
246
|
+
return "RT";
|
|
247
|
+
}
|
|
248
|
+
if (status === SubmissionStatus.COMPILATION_ERROR || isNotCalculatedPenaltyStatus(status)) {
|
|
249
|
+
return "CE";
|
|
250
|
+
}
|
|
251
|
+
if (isPending(status)) {
|
|
252
|
+
return "PD";
|
|
253
|
+
}
|
|
254
|
+
return "RJ";
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
class GeneralExcelConverter {
|
|
259
|
+
constructor() {
|
|
260
|
+
}
|
|
261
|
+
convert(rank) {
|
|
262
|
+
const workbook = XLSX.utils.book_new();
|
|
263
|
+
const aoa = this.convertToAoa(rank);
|
|
264
|
+
const mainWorksheet = XLSX.utils.aoa_to_sheet(aoa);
|
|
265
|
+
const cols = [];
|
|
266
|
+
const head = aoa[1];
|
|
267
|
+
for (let j = 0; j < head.length; j++) {
|
|
268
|
+
let wch = 10;
|
|
269
|
+
for (let i = 1; i < aoa.length; i++) {
|
|
270
|
+
wch = Math.max(wch, stringWidth(aoa[i][j]) + 2);
|
|
271
|
+
}
|
|
272
|
+
cols.push({
|
|
273
|
+
wch
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
mainWorksheet["!cols"] = cols;
|
|
277
|
+
{
|
|
278
|
+
const mergeRange = { s: { r: 0, c: 0 }, e: { r: 0, c: head.length - 1 } };
|
|
279
|
+
const merges = [{ s: mergeRange.s, e: mergeRange.e }];
|
|
280
|
+
mainWorksheet["!merges"] = merges;
|
|
281
|
+
}
|
|
282
|
+
const font = {
|
|
283
|
+
name: "Arial Unicode MS",
|
|
284
|
+
bold: false,
|
|
285
|
+
italic: false,
|
|
286
|
+
sz: 12
|
|
287
|
+
};
|
|
288
|
+
const borderStyle = {
|
|
289
|
+
style: "thin"
|
|
290
|
+
};
|
|
291
|
+
const cellStyle = {
|
|
292
|
+
alignment: {
|
|
293
|
+
vertical: "center",
|
|
294
|
+
horizontal: "center"
|
|
295
|
+
},
|
|
296
|
+
border: {
|
|
297
|
+
top: borderStyle,
|
|
298
|
+
bottom: borderStyle,
|
|
299
|
+
left: borderStyle,
|
|
300
|
+
right: borderStyle
|
|
301
|
+
},
|
|
302
|
+
font
|
|
303
|
+
};
|
|
304
|
+
for (let i = 1; i < aoa.length; i++) {
|
|
305
|
+
for (let j = 0; j < aoa[i].length; j++) {
|
|
306
|
+
const cellAddress = XLSX.utils.encode_cell({ r: i, c: j });
|
|
307
|
+
const cell = mainWorksheet[cellAddress];
|
|
308
|
+
cell.s = cellStyle;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
{
|
|
312
|
+
const cellAddress = XLSX.utils.encode_cell({ r: 0, c: 0 });
|
|
313
|
+
const cell = mainWorksheet[cellAddress];
|
|
314
|
+
const titleStyle = _.cloneDeep(cellStyle);
|
|
315
|
+
titleStyle.font.sz = 28;
|
|
316
|
+
titleStyle.font.bold = true;
|
|
317
|
+
cell.s = titleStyle;
|
|
318
|
+
}
|
|
319
|
+
XLSX.utils.book_append_sheet(workbook, mainWorksheet, "Scoreboard");
|
|
320
|
+
return workbook;
|
|
321
|
+
}
|
|
322
|
+
convertAndWrite(rank, filename) {
|
|
323
|
+
return XLSX.writeFile(
|
|
324
|
+
this.convert(rank),
|
|
325
|
+
filename,
|
|
326
|
+
{
|
|
327
|
+
compression: true
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
convertToAoa(rank) {
|
|
332
|
+
const aoa = [];
|
|
333
|
+
{
|
|
334
|
+
aoa.push([rank.contest.name]);
|
|
335
|
+
}
|
|
336
|
+
{
|
|
337
|
+
const head = [];
|
|
338
|
+
head.push("Rank");
|
|
339
|
+
if (rank.contest.organization) {
|
|
340
|
+
head.push(`${rank.contest.organization} Rank`);
|
|
341
|
+
head.push(rank.contest.organization);
|
|
342
|
+
}
|
|
343
|
+
head.push("Name", "Solved", "Penalty", ...rank.contest.problems.map((p) => p.label), "Dict");
|
|
344
|
+
aoa.push(head);
|
|
345
|
+
}
|
|
346
|
+
for (const team of rank.teams) {
|
|
347
|
+
const arr = [];
|
|
348
|
+
arr.push(team.rank.toString());
|
|
349
|
+
if (team.organization) {
|
|
350
|
+
if (team.organizationRank !== -1) {
|
|
351
|
+
arr.push(team.organizationRank.toString());
|
|
352
|
+
} else {
|
|
353
|
+
arr.push("");
|
|
354
|
+
}
|
|
355
|
+
arr.push(team.organization);
|
|
356
|
+
}
|
|
357
|
+
arr.push(team.name, team.solvedProblemNum.toString(), team.penaltyToMinute.toString());
|
|
358
|
+
for (const p of team.problemStatistics) {
|
|
359
|
+
if (p.isUnSubmitted) {
|
|
360
|
+
arr.push("-");
|
|
361
|
+
}
|
|
362
|
+
if (p.isSolved) {
|
|
363
|
+
arr.push(`+${p.totalCount}(${p.solvedTimestampToMinute})`);
|
|
364
|
+
}
|
|
365
|
+
if (p.isWrongAnswer) {
|
|
366
|
+
arr.push(`-${p.failedCount}`);
|
|
367
|
+
}
|
|
368
|
+
if (p.isPending) {
|
|
369
|
+
arr.push(`? ${p.failedCount} + ${p.pendingCount}`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
arr.push(`${team.dict}%`);
|
|
373
|
+
aoa.push(arr);
|
|
374
|
+
}
|
|
375
|
+
return aoa;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
var MedalType = /* @__PURE__ */ ((MedalType2) => {
|
|
380
|
+
MedalType2[MedalType2["UNKNOWN"] = 0] = "UNKNOWN";
|
|
381
|
+
MedalType2[MedalType2["GOLD"] = 1] = "GOLD";
|
|
382
|
+
MedalType2[MedalType2["SILVER"] = 2] = "SILVER";
|
|
383
|
+
MedalType2[MedalType2["BRONZE"] = 3] = "BRONZE";
|
|
384
|
+
MedalType2[MedalType2["HONORABLE"] = 4] = "HONORABLE";
|
|
385
|
+
return MedalType2;
|
|
386
|
+
})(MedalType || {});
|
|
387
|
+
class Award {
|
|
388
|
+
constructor() {
|
|
389
|
+
this.medalType = 0 /* UNKNOWN */;
|
|
390
|
+
this.minRank = 0;
|
|
391
|
+
this.maxRank = 0;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function calcDict(attemptedNum, solvedNum) {
|
|
396
|
+
if (solvedNum === 0) {
|
|
397
|
+
return 0;
|
|
398
|
+
}
|
|
399
|
+
return Math.floor((attemptedNum - solvedNum) * 100 / attemptedNum);
|
|
400
|
+
}
|
|
401
|
+
|
|
73
402
|
class ProblemStatistics {
|
|
74
403
|
constructor() {
|
|
75
404
|
this.acceptedNum = 0;
|
|
@@ -175,6 +504,12 @@ class TeamProblemStatistics {
|
|
|
175
504
|
}
|
|
176
505
|
return Math.floor(this.solvedTimestamp / 60) * 60 + this.failedCount * this.contestPenalty;
|
|
177
506
|
}
|
|
507
|
+
get penaltyToMinute() {
|
|
508
|
+
return Math.floor(this.penalty / 60);
|
|
509
|
+
}
|
|
510
|
+
get solvedTimestampToMinute() {
|
|
511
|
+
return Math.floor(this.solvedTimestamp / 60);
|
|
512
|
+
}
|
|
178
513
|
}
|
|
179
514
|
|
|
180
515
|
class Group {
|
|
@@ -424,208 +759,6 @@ function createContestIndexList(contestListJSON) {
|
|
|
424
759
|
return contestIndexList;
|
|
425
760
|
}
|
|
426
761
|
|
|
427
|
-
function stringToSubmissionStatus(status) {
|
|
428
|
-
status = status.toUpperCase().replace(" ", "_");
|
|
429
|
-
if (["OK", "AC", SubmissionStatus.ACCEPTED.toString()].includes(status)) {
|
|
430
|
-
return SubmissionStatus.ACCEPTED;
|
|
431
|
-
}
|
|
432
|
-
if ([SubmissionStatus.CORRECT.toString()].includes(status)) {
|
|
433
|
-
return SubmissionStatus.ACCEPTED;
|
|
434
|
-
}
|
|
435
|
-
if ([SubmissionStatus.PARTIALLY_CORRECT.toString()].includes(status)) {
|
|
436
|
-
return SubmissionStatus.PARTIALLY_CORRECT;
|
|
437
|
-
}
|
|
438
|
-
if (["WA", SubmissionStatus.WRONG_ANSWER.toString()].includes(status)) {
|
|
439
|
-
return SubmissionStatus.WRONG_ANSWER;
|
|
440
|
-
}
|
|
441
|
-
if (["RJ", "INCORRECT", SubmissionStatus.REJECTED.toString()].includes(status)) {
|
|
442
|
-
return SubmissionStatus.REJECTED;
|
|
443
|
-
}
|
|
444
|
-
if (["PD", SubmissionStatus.PENDING.toString()].includes(status)) {
|
|
445
|
-
return SubmissionStatus.PENDING;
|
|
446
|
-
}
|
|
447
|
-
if ([SubmissionStatus.WAITING.toString()].includes(status)) {
|
|
448
|
-
return SubmissionStatus.WAITING;
|
|
449
|
-
}
|
|
450
|
-
if ([SubmissionStatus.JUDGING.toString()].includes(status)) {
|
|
451
|
-
return SubmissionStatus.JUDGING;
|
|
452
|
-
}
|
|
453
|
-
if ([SubmissionStatus.FROZEN.toString()].includes(status)) {
|
|
454
|
-
return SubmissionStatus.FROZEN;
|
|
455
|
-
}
|
|
456
|
-
if (["CE", SubmissionStatus.COMPILATION_ERROR.toString()].includes(status)) {
|
|
457
|
-
return SubmissionStatus.COMPILATION_ERROR;
|
|
458
|
-
}
|
|
459
|
-
if (["PE", SubmissionStatus.PRESENTATION_ERROR.toString()].includes(status)) {
|
|
460
|
-
return SubmissionStatus.PRESENTATION_ERROR;
|
|
461
|
-
}
|
|
462
|
-
if (["TL", "TLE", SubmissionStatus.TIME_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
463
|
-
return SubmissionStatus.TIME_LIMIT_EXCEEDED;
|
|
464
|
-
}
|
|
465
|
-
if (["ML", "MLE", SubmissionStatus.MEMORY_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
466
|
-
return SubmissionStatus.MEMORY_LIMIT_EXCEEDED;
|
|
467
|
-
}
|
|
468
|
-
if (["OL", "OLE", SubmissionStatus.OUTPUT_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
469
|
-
return SubmissionStatus.OUTPUT_LIMIT_EXCEEDED;
|
|
470
|
-
}
|
|
471
|
-
if (["IL", "ILE", SubmissionStatus.IDLENESS_LIMIT_EXCEEDED.toString()].includes(status)) {
|
|
472
|
-
return SubmissionStatus.IDLENESS_LIMIT_EXCEEDED;
|
|
473
|
-
}
|
|
474
|
-
if (["RT", "RE", "RTE", SubmissionStatus.RUNTIME_ERROR.toString()].includes(status)) {
|
|
475
|
-
return SubmissionStatus.RUNTIME_ERROR;
|
|
476
|
-
}
|
|
477
|
-
if (["JE", SubmissionStatus.JUDGEMENT_FAILED.toString()].includes(status)) {
|
|
478
|
-
return SubmissionStatus.JUDGEMENT_FAILED;
|
|
479
|
-
}
|
|
480
|
-
if (["SE", SubmissionStatus.SYSTEM_ERROR.toString()].includes(status)) {
|
|
481
|
-
return SubmissionStatus.SYSTEM_ERROR;
|
|
482
|
-
}
|
|
483
|
-
if ([SubmissionStatus.HACKED.toString()].includes(status)) {
|
|
484
|
-
return SubmissionStatus.HACKED;
|
|
485
|
-
}
|
|
486
|
-
if ([SubmissionStatus.CONFIGURATION_ERROR.toString()].includes(status)) {
|
|
487
|
-
return SubmissionStatus.CONFIGURATION_ERROR;
|
|
488
|
-
}
|
|
489
|
-
if ([SubmissionStatus.CANCELED.toString()].includes(status)) {
|
|
490
|
-
return SubmissionStatus.CANCELED;
|
|
491
|
-
}
|
|
492
|
-
if ([SubmissionStatus.SKIPPED.toString()].includes(status)) {
|
|
493
|
-
return SubmissionStatus.SKIPPED;
|
|
494
|
-
}
|
|
495
|
-
if ([SubmissionStatus.SECURITY_VIOLATED.toString()].includes(status)) {
|
|
496
|
-
return SubmissionStatus.SECURITY_VIOLATED;
|
|
497
|
-
}
|
|
498
|
-
if ([SubmissionStatus.DENIAL_OF_JUDGEMENT.toString()].includes(status)) {
|
|
499
|
-
return SubmissionStatus.DENIAL_OF_JUDGEMENT;
|
|
500
|
-
}
|
|
501
|
-
return SubmissionStatus.UNKNOWN;
|
|
502
|
-
}
|
|
503
|
-
function isAccepted(status) {
|
|
504
|
-
const acceptedArray = [SubmissionStatus.ACCEPTED, SubmissionStatus.CORRECT];
|
|
505
|
-
return acceptedArray.includes(status);
|
|
506
|
-
}
|
|
507
|
-
function isRejected(status) {
|
|
508
|
-
const rejectArray = [
|
|
509
|
-
SubmissionStatus.RUNTIME_ERROR,
|
|
510
|
-
SubmissionStatus.TIME_LIMIT_EXCEEDED,
|
|
511
|
-
SubmissionStatus.MEMORY_LIMIT_EXCEEDED,
|
|
512
|
-
SubmissionStatus.OUTPUT_LIMIT_EXCEEDED,
|
|
513
|
-
SubmissionStatus.IDLENESS_LIMIT_EXCEEDED,
|
|
514
|
-
SubmissionStatus.WRONG_ANSWER,
|
|
515
|
-
SubmissionStatus.REJECTED,
|
|
516
|
-
SubmissionStatus.JUDGEMENT_FAILED,
|
|
517
|
-
SubmissionStatus.HACKED
|
|
518
|
-
];
|
|
519
|
-
return rejectArray.includes(status);
|
|
520
|
-
}
|
|
521
|
-
function isPending(status) {
|
|
522
|
-
const pendingArray = [
|
|
523
|
-
SubmissionStatus.PENDING,
|
|
524
|
-
SubmissionStatus.WAITING,
|
|
525
|
-
SubmissionStatus.JUDGING,
|
|
526
|
-
SubmissionStatus.FROZEN
|
|
527
|
-
];
|
|
528
|
-
return pendingArray.includes(status);
|
|
529
|
-
}
|
|
530
|
-
function isNotCalculatedPenaltyStatus(status) {
|
|
531
|
-
const isNotCalculatedPenaltyArray = [
|
|
532
|
-
SubmissionStatus.COMPILATION_ERROR,
|
|
533
|
-
SubmissionStatus.PRESENTATION_ERROR,
|
|
534
|
-
SubmissionStatus.CONFIGURATION_ERROR,
|
|
535
|
-
SubmissionStatus.SYSTEM_ERROR,
|
|
536
|
-
SubmissionStatus.CANCELED,
|
|
537
|
-
SubmissionStatus.SKIPPED,
|
|
538
|
-
SubmissionStatus.UNKNOWN,
|
|
539
|
-
SubmissionStatus.UNDEFINED
|
|
540
|
-
];
|
|
541
|
-
return isNotCalculatedPenaltyArray.includes(status);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
function submissionStatusToCodeforcesGymDatStatus(status) {
|
|
545
|
-
if (isAccepted(status)) {
|
|
546
|
-
return "OK";
|
|
547
|
-
}
|
|
548
|
-
if (status === SubmissionStatus.WRONG_ANSWER) {
|
|
549
|
-
return "WA";
|
|
550
|
-
}
|
|
551
|
-
if (status === SubmissionStatus.TIME_LIMIT_EXCEEDED) {
|
|
552
|
-
return "TL";
|
|
553
|
-
}
|
|
554
|
-
if (status === SubmissionStatus.MEMORY_LIMIT_EXCEEDED) {
|
|
555
|
-
return "ML";
|
|
556
|
-
}
|
|
557
|
-
if (status === SubmissionStatus.OUTPUT_LIMIT_EXCEEDED) {
|
|
558
|
-
return "IL";
|
|
559
|
-
}
|
|
560
|
-
if (status === SubmissionStatus.PRESENTATION_ERROR) {
|
|
561
|
-
return "PE";
|
|
562
|
-
}
|
|
563
|
-
if (status === SubmissionStatus.RUNTIME_ERROR) {
|
|
564
|
-
return "RT";
|
|
565
|
-
}
|
|
566
|
-
if (status === SubmissionStatus.COMPILATION_ERROR || isNotCalculatedPenaltyStatus(status)) {
|
|
567
|
-
return "CE";
|
|
568
|
-
}
|
|
569
|
-
if (isPending(status)) {
|
|
570
|
-
return "PD";
|
|
571
|
-
}
|
|
572
|
-
return "RJ";
|
|
573
|
-
}
|
|
574
|
-
function rankToCodeforcesGymDAT(rank) {
|
|
575
|
-
let res = "";
|
|
576
|
-
res += `@contest "${rank.contest.name}"
|
|
577
|
-
@contlen ${Math.floor(dayjs.duration(rank.contest.endTime.diff(rank.contest.startTime)).asMinutes())}
|
|
578
|
-
@problems ${rank.contest.problems.length}
|
|
579
|
-
@teams ${rank.teams.length + 100}
|
|
580
|
-
@submissions ${rank.submissions.length}
|
|
581
|
-
`;
|
|
582
|
-
rank.contest.problems.forEach((p) => {
|
|
583
|
-
res += `@p ${p.label},${p.label},20,0
|
|
584
|
-
`;
|
|
585
|
-
});
|
|
586
|
-
let teamIndex = 1;
|
|
587
|
-
const teamIdMap = /* @__PURE__ */ new Map();
|
|
588
|
-
const submissionsIdMap = /* @__PURE__ */ new Map();
|
|
589
|
-
rank.teams.forEach((team) => {
|
|
590
|
-
let name = team.name;
|
|
591
|
-
if (team.organization) {
|
|
592
|
-
name = `${team.organization} - ${name}`;
|
|
593
|
-
}
|
|
594
|
-
if (team.members) {
|
|
595
|
-
name = `${name} - ${team.membersToString}`;
|
|
596
|
-
}
|
|
597
|
-
res += `@t ${teamIndex},0,1,${name}
|
|
598
|
-
`;
|
|
599
|
-
teamIdMap.set(team.id, teamIndex);
|
|
600
|
-
teamIndex++;
|
|
601
|
-
{
|
|
602
|
-
const mp = /* @__PURE__ */ new Map();
|
|
603
|
-
rank.contest.problems.forEach((p) => {
|
|
604
|
-
mp.set(p.id, 0);
|
|
605
|
-
});
|
|
606
|
-
submissionsIdMap.set(team.id, mp);
|
|
607
|
-
}
|
|
608
|
-
});
|
|
609
|
-
for (let i = 0; i < 100; i++) {
|
|
610
|
-
res += `@t ${teamIndex},0,1,\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043A\u043E\u043C\u0430\u043D\u0434\u0443
|
|
611
|
-
`;
|
|
612
|
-
teamIndex++;
|
|
613
|
-
}
|
|
614
|
-
rank.getSubmissions().forEach((submission) => {
|
|
615
|
-
const teamId = submission.teamId;
|
|
616
|
-
const problemId = submission.problemId;
|
|
617
|
-
const problem = rank.contest.problemsMap.get(problemId);
|
|
618
|
-
if (!problem) {
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
const status = submissionStatusToCodeforcesGymDatStatus(submission.status);
|
|
622
|
-
submissionsIdMap.get(teamId).set(problemId, submissionsIdMap.get(teamId).get(problemId) + 1);
|
|
623
|
-
res += `@s ${teamIdMap.get(teamId)},${problem.label},${submissionsIdMap.get(teamId)?.get(problemId)},${submission.timestamp},${status}
|
|
624
|
-
`;
|
|
625
|
-
});
|
|
626
|
-
return res;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
762
|
function getImageSource(image) {
|
|
630
763
|
if (image?.url) {
|
|
631
764
|
return image.url;
|
|
@@ -1227,4 +1360,4 @@ class Resolver extends Rank {
|
|
|
1227
1360
|
}
|
|
1228
1361
|
}
|
|
1229
1362
|
|
|
1230
|
-
export { Award, Contest, ContestIndex, ContestIndexConfig, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Resolver, Submission, Team, TeamProblemStatistics, calcDict, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected,
|
|
1363
|
+
export { Award, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, GeneralExcelConverter, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Resolver, Submission, Team, TeamProblemStatistics, calcDict, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, stringToSubmissionStatus };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xcpcio/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "XCPCIO Core",
|
|
5
5
|
"author": "Dup4 <lyuzhi.pan@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"dayjs": "^1.11.8",
|
|
44
44
|
"lodash": "^4.17.21",
|
|
45
|
-
"
|
|
45
|
+
"string-width": "^6.1.0",
|
|
46
|
+
"xlsx-js-style": "^1.2.0",
|
|
47
|
+
"@xcpcio/types": "0.14.0"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
48
50
|
"@babel/types": "^7.22.4",
|