@xcpcio/core 0.58.0 → 0.59.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.
@@ -1,81 +0,0 @@
1
- import type { IRatingHistory } from "@xcpcio/types";
2
- import type { Persons } from "../person";
3
- import type { dayjs } from "../utils";
4
-
5
- import { Person } from "../person";
6
- import { createDayJS } from "../utils";
7
-
8
- export class RatingHistory {
9
- rank: number;
10
- rating: number;
11
-
12
- teamName: string;
13
- organization: string;
14
-
15
- members: Persons;
16
- coaches: Persons;
17
-
18
- contestID: string;
19
- contestName: string;
20
- contestLink: string;
21
- contestTime: dayjs.Dayjs;
22
-
23
- constructor() {
24
- this.rank = 0;
25
- this.rating = 0;
26
-
27
- this.teamName = "";
28
- this.organization = "";
29
-
30
- this.members = [];
31
- this.coaches = [];
32
-
33
- this.contestID = "";
34
- this.contestName = "";
35
- this.contestLink = "";
36
- this.contestTime = createDayJS();
37
- }
38
-
39
- toJSON(): IRatingHistory {
40
- return {
41
- rank: this.rank,
42
- rating: this.rating,
43
-
44
- teamName: this.teamName,
45
- organization: this.organization,
46
-
47
- members: this.members.map(member => member.toJSON()),
48
- coaches: this.coaches.map(coach => coach.toJSON()),
49
-
50
- contestID: this.contestID,
51
- contestName: this.contestName,
52
- contestLink: this.contestLink,
53
- contestTime: this.contestTime.toDate(),
54
- };
55
- }
56
-
57
- static fromJSON(iRatingHistory: IRatingHistory | string): RatingHistory {
58
- if (typeof iRatingHistory === "string") {
59
- iRatingHistory = JSON.parse(iRatingHistory) as IRatingHistory;
60
- }
61
-
62
- const ratingHistory = new RatingHistory();
63
- ratingHistory.rank = iRatingHistory.rank;
64
- ratingHistory.rating = iRatingHistory.rating;
65
-
66
- ratingHistory.teamName = iRatingHistory.teamName;
67
- ratingHistory.organization = iRatingHistory.organization;
68
-
69
- ratingHistory.members = iRatingHistory.members.map(iMember => Person.fromJSON(iMember));
70
- ratingHistory.coaches = iRatingHistory.coaches.map(iCoach => Person.fromJSON(iCoach));
71
-
72
- ratingHistory.contestID = iRatingHistory.contestID;
73
- ratingHistory.contestName = iRatingHistory.contestName;
74
- ratingHistory.contestLink = iRatingHistory.contestLink;
75
- ratingHistory.contestTime = createDayJS(iRatingHistory.contestTime);
76
-
77
- return ratingHistory;
78
- }
79
- }
80
-
81
- export type RatingHistories = Array<RatingHistory>;
@@ -1,99 +0,0 @@
1
- import type { IRatingUser } from "@xcpcio/types";
2
-
3
- import type { Persons } from "../person";
4
- import type { RatingHistories } from "./rating-history";
5
- import { Person } from "../person";
6
- import { RatingHistory } from "./rating-history";
7
-
8
- export class RatingUser {
9
- id: string;
10
- name: string;
11
- organization: string;
12
-
13
- members: Persons;
14
- coaches: Persons;
15
-
16
- rating: number;
17
- minRating: number;
18
- maxRating: number;
19
-
20
- rank: number;
21
- oldRating: number;
22
-
23
- seed: number;
24
- delta: number;
25
-
26
- ratingHistories: RatingHistories;
27
-
28
- constructor() {
29
- this.id = "";
30
- this.name = "";
31
- this.organization = "";
32
-
33
- this.members = [];
34
- this.coaches = [];
35
-
36
- this.rating = 0;
37
- this.minRating = 0x3F3F3F3F;
38
- this.maxRating = -0x3F3F3F3F;
39
-
40
- this.rank = 0;
41
- this.oldRating = 0;
42
-
43
- this.seed = 1.0;
44
- this.delta = 0;
45
-
46
- this.ratingHistories = [];
47
- }
48
-
49
- UpdateRating(rating: number) {
50
- this.rating = rating;
51
- this.minRating = Math.min(this.minRating, rating);
52
- this.maxRating = Math.max(this.maxRating, rating);
53
- }
54
-
55
- toJSON(): IRatingUser {
56
- return {
57
- id: this.id,
58
- name: this.name,
59
- organization: this.organization,
60
-
61
- members: this.members.map(member => member.toJSON()),
62
- coaches: this.coaches.map(coach => coach.toJSON()),
63
-
64
- rating: this.rating,
65
- minRating: this.minRating,
66
- maxRating: this.maxRating,
67
-
68
- ratingHistories: this.ratingHistories.map(ratingHistory => ratingHistory.toJSON()),
69
- };
70
- }
71
-
72
- static fromJSON(iRatingUser: IRatingUser | string): RatingUser {
73
- if (typeof iRatingUser === "string") {
74
- iRatingUser = JSON.parse(iRatingUser) as IRatingUser;
75
- }
76
-
77
- const ratingUser = new RatingUser();
78
-
79
- ratingUser.id = iRatingUser.id;
80
- ratingUser.name = iRatingUser.name;
81
- ratingUser.organization = iRatingUser.organization;
82
-
83
- ratingUser.members = iRatingUser.members.map(member => Person.fromJSON(member));
84
- ratingUser.coaches = iRatingUser.coaches.map(coach => Person.fromJSON(coach));
85
-
86
- ratingUser.rating = iRatingUser.rating;
87
- ratingUser.minRating = iRatingUser.minRating;
88
- ratingUser.maxRating = iRatingUser.maxRating;
89
-
90
- for (const iRatingHistory of iRatingUser.ratingHistories) {
91
- ratingUser.ratingHistories.push(RatingHistory.fromJSON(iRatingHistory));
92
- }
93
-
94
- return ratingUser;
95
- }
96
- }
97
-
98
- export type RatingUsers = Array<RatingUser>;
99
- export type RatingUserMap = Map<string, RatingUser>;
@@ -1,80 +0,0 @@
1
- export enum RatingLevel {
2
- NEWBIE = "NEWBIE",
3
- PUPIL = "PUPIL",
4
- SPECIALIST = "SPECIALIST",
5
- EXPERT = "EXPERT",
6
- CANDIDATE_MASTER = "CANDIDATE_MASTER",
7
- MASTER = "MASTER",
8
- INTERNATIONAL_MASTER = "INTERNATIONAL_MASTER",
9
- GRANDMASTER = "GRANDMASTER",
10
- INTERNATIONAL_GRANDMASTER = "INTERNATIONAL_GRANDMASTER",
11
- LEGENDARY_GRANDMASTER = "LEGENDARY_GRANDMASTER",
12
- }
13
-
14
- export const RatingLevelToString: { [key in RatingLevel]: string } = {
15
- [RatingLevel.NEWBIE]: "Newbie",
16
- [RatingLevel.PUPIL]: "Pupil",
17
- [RatingLevel.SPECIALIST]: "Specialist",
18
- [RatingLevel.EXPERT]: "Expert",
19
- [RatingLevel.CANDIDATE_MASTER]: "Candidate Master",
20
- [RatingLevel.MASTER]: "Master",
21
- [RatingLevel.INTERNATIONAL_MASTER]: "International Master",
22
- [RatingLevel.GRANDMASTER]: "Grandmaster",
23
- [RatingLevel.INTERNATIONAL_GRANDMASTER]: "International Grandmaster",
24
- [RatingLevel.LEGENDARY_GRANDMASTER]: "Legendary Grandmaster",
25
- };
26
-
27
- export class RatingUtility {
28
- static getRatingLevel(rating: number): RatingLevel {
29
- if (rating >= 3000) {
30
- return RatingLevel.LEGENDARY_GRANDMASTER;
31
- } else if (rating >= 2600) {
32
- return RatingLevel.INTERNATIONAL_GRANDMASTER;
33
- } else if (rating >= 2400) {
34
- return RatingLevel.GRANDMASTER;
35
- } else if (rating >= 2300) {
36
- return RatingLevel.INTERNATIONAL_MASTER;
37
- } else if (rating >= 2100) {
38
- return RatingLevel.MASTER;
39
- } else if (rating >= 1900) {
40
- return RatingLevel.CANDIDATE_MASTER;
41
- } else if (rating >= 1600) {
42
- return RatingLevel.EXPERT;
43
- } else if (rating >= 1400) {
44
- return RatingLevel.SPECIALIST;
45
- } else if (rating >= 1200) {
46
- return RatingLevel.PUPIL;
47
- }
48
-
49
- return RatingLevel.NEWBIE;
50
- }
51
-
52
- static getRatingLevelClass(ratingLevel: RatingLevel | number): string {
53
- if (typeof ratingLevel === "number") {
54
- return this.getRatingLevelClass(this.getRatingLevel(ratingLevel));
55
- }
56
-
57
- switch (ratingLevel) {
58
- case RatingLevel.NEWBIE:
59
- return "user-gray";
60
- case RatingLevel.PUPIL:
61
- return "user-green";
62
- case RatingLevel.SPECIALIST:
63
- return "user-cyan";
64
- case RatingLevel.EXPERT:
65
- return "user-blue";
66
- case RatingLevel.CANDIDATE_MASTER:
67
- return "user-violet";
68
- case RatingLevel.MASTER:
69
- return "user-orange";
70
- case RatingLevel.INTERNATIONAL_MASTER:
71
- return "user-orange";
72
- case RatingLevel.GRANDMASTER:
73
- return "user-red";
74
- case RatingLevel.INTERNATIONAL_GRANDMASTER:
75
- return "user-red";
76
- case RatingLevel.LEGENDARY_GRANDMASTER:
77
- return "user-legendary";
78
- }
79
- }
80
- }
@@ -1,136 +0,0 @@
1
- import type { IRating } from "@xcpcio/types";
2
- import type { Ranks } from "../rank";
3
- import type { Team } from "../team";
4
- import type { RatingUserMap, RatingUsers } from "./rating-user";
5
-
6
- import { createPersons } from "../person";
7
- import { RatingCalculator } from "./rating-calculator";
8
- import { RatingHistory } from "./rating-history";
9
- import { RatingUser } from "./rating-user";
10
-
11
- export class Rating {
12
- id: string;
13
- name: string;
14
- baseRating: number;
15
-
16
- contestIDs: string[];
17
- users: RatingUsers;
18
-
19
- ranks: Ranks;
20
- userMap: RatingUserMap;
21
-
22
- constructor() {
23
- this.id = "";
24
- this.name = "";
25
- this.baseRating = 1500;
26
-
27
- this.contestIDs = [];
28
- this.users = [];
29
-
30
- this.ranks = [];
31
- this.userMap = new Map<string, RatingUser>();
32
- }
33
-
34
- buildRating() {
35
- for (const rank of this.ranks) {
36
- rank.buildRank();
37
-
38
- const ratingCalculator = new RatingCalculator();
39
-
40
- for (const t of rank.teams) {
41
- const id = this.generateTeamId(t);
42
-
43
- let u = null;
44
-
45
- if (!this.userMap.has(id)) {
46
- u = new RatingUser();
47
- u.id = id;
48
- u.name = t.name;
49
- u.organization = t.organization;
50
-
51
- u.members = createPersons(t.members ?? []);
52
- u.coaches = createPersons(t.coach ?? []);
53
-
54
- u.rank = t.rank;
55
- u.oldRating = this.baseRating;
56
- u.UpdateRating(this.baseRating);
57
-
58
- this.userMap.set(id, u);
59
- this.users.push(u);
60
-
61
- ratingCalculator.users.push(u);
62
- } else {
63
- u = this.userMap.get(id)!;
64
- u.rank = t.rank;
65
- u.oldRating = u.rating;
66
- ratingCalculator.users.push(u);
67
- }
68
-
69
- {
70
- const h = new RatingHistory();
71
- h.rank = t.rank;
72
- h.rating = u.rating;
73
-
74
- h.teamName = t.name;
75
- h.organization = t.organization;
76
-
77
- h.members = createPersons(t.members ?? []);
78
- h.coaches = createPersons(t.coach ?? []);
79
-
80
- h.contestID = rank.contest.id;
81
- h.contestLink = h.contestID;
82
- h.contestName = rank.contest.name;
83
- h.contestTime = rank.contest.startTime;
84
-
85
- u.ratingHistories.push(h);
86
- }
87
- }
88
-
89
- ratingCalculator.calculate();
90
-
91
- for (const u of ratingCalculator.users) {
92
- u.ratingHistories.at(-1)!.rating = u.rating;
93
- }
94
- }
95
- }
96
-
97
- generateTeamId(t: Team) {
98
- const persons = createPersons(t.members ?? []);
99
- if (persons.length > 0) {
100
- return persons.map(person => person.name.trim()).sort().join("|");
101
- }
102
-
103
- return `${t.organization}-${t.name}`;
104
- }
105
-
106
- toJSON(): IRating {
107
- return {
108
- id: this.id,
109
- name: this.name,
110
- baseRating: this.baseRating,
111
-
112
- contestIDs: this.contestIDs,
113
- users: this.users.map(ratingUser => ratingUser.toJSON()),
114
- };
115
- }
116
-
117
- static fromJSON(iRating: IRating | string): Rating {
118
- if (typeof iRating === "string") {
119
- iRating = JSON.parse(iRating) as IRating;
120
- }
121
-
122
- const rating = new Rating();
123
-
124
- rating.id = iRating.id;
125
- rating.name = iRating.name;
126
- rating.baseRating = iRating.baseRating;
127
-
128
- rating.contestIDs = iRating.contestIDs;
129
-
130
- for (const iUser of iRating.users) {
131
- rating.users.push(RatingUser.fromJSON(iUser));
132
- }
133
-
134
- return rating;
135
- }
136
- }
@@ -1,22 +0,0 @@
1
- import { TeamProblemStatistics } from "./problem";
2
- import { Team } from "./team";
3
-
4
- export class ResolverOperation {
5
- id: number;
6
-
7
- team: Team;
8
- problemIx: number;
9
-
10
- beforeTeamProblemStatistics: TeamProblemStatistics;
11
- afterTeamProblemStatistics: TeamProblemStatistics;
12
-
13
- constructor() {
14
- this.id = 0;
15
-
16
- this.team = new Team();
17
- this.problemIx = 0;
18
-
19
- this.beforeTeamProblemStatistics = new TeamProblemStatistics();
20
- this.afterTeamProblemStatistics = new TeamProblemStatistics();
21
- }
22
- }
@@ -1,183 +0,0 @@
1
- import type { Contest } from "./contest";
2
- import type { Submissions } from "./submission";
3
- import type { Teams } from "./team";
4
-
5
- import { Resolver } from "./resolver";
6
- import { Team } from "./team";
7
-
8
- export class ResolverVue extends Resolver {
9
- readonly FLASHING_TIME_MS = 100;
10
- readonly ROLLING_TIME_MS = 600;
11
-
12
- maxIndex: number;
13
- currentIndex: number;
14
-
15
- maxOpIndex: number;
16
- currentOpIndex: number;
17
-
18
- oldRank: number;
19
- newRank: number;
20
-
21
- currentTeamId: string;
22
- currentProblemIndex: number;
23
-
24
- problemFlashingEnded: boolean;
25
- duringAnimation: boolean;
26
-
27
- startScrollUp: boolean;
28
- startScrollDown: boolean;
29
-
30
- constructor(contest: Contest, teams: Teams, submissions: Submissions) {
31
- super(contest, teams, submissions);
32
-
33
- this.maxIndex = 0;
34
- this.currentIndex = 0;
35
-
36
- this.maxOpIndex = 0;
37
- this.currentOpIndex = 0;
38
-
39
- this.oldRank = -1;
40
- this.newRank = -1;
41
-
42
- this.currentTeamId = "";
43
- this.currentProblemIndex = -1;
44
-
45
- this.problemFlashingEnded = true;
46
- this.duringAnimation = false;
47
-
48
- this.startScrollUp = false;
49
- this.startScrollDown = false;
50
- }
51
-
52
- buildResolver() {
53
- super.buildResolver();
54
-
55
- this.maxIndex = this.teams.length - 1;
56
- this.currentIndex = this.maxIndex;
57
-
58
- this.maxOpIndex = this.operations.length - 1;
59
- this.currentOpIndex = 0;
60
-
61
- this.oldRank = -1;
62
- this.newRank = -1;
63
-
64
- this.currentTeamId = "";
65
- this.currentProblemIndex = -1;
66
-
67
- this.problemFlashingEnded = true;
68
- this.duringAnimation = false;
69
-
70
- this.startScrollUp = false;
71
- this.startScrollDown = false;
72
- }
73
-
74
- next() {
75
- if (this.duringAnimation) {
76
- return;
77
- }
78
-
79
- if (this.currentOpIndex > this.maxOpIndex) {
80
- if (this.currentIndex > 0) {
81
- this.currentIndex--;
82
- }
83
-
84
- return;
85
- }
86
-
87
- const op = this.operations[this.currentOpIndex];
88
- const pIx = op.problemIx;
89
- const teamId = op.team.id;
90
- const team = this.teamsMap.get(teamId) as Team;
91
- const currentRank = team.rank;
92
-
93
- if (this.currentIndex + 1 > currentRank) {
94
- this.currentIndex--;
95
- return;
96
- }
97
-
98
- if (this.currentIndex + 1 !== currentRank) {
99
- return;
100
- }
101
-
102
- team.problemStatistics[pIx] = op.afterTeamProblemStatistics;
103
- team.calcSolvedData(this.contest.options);
104
-
105
- this.currentProblemIndex = pIx;
106
- this.currentTeamId = teamId;
107
-
108
- {
109
- this.oldRank = team.rank;
110
- this.newRank = this.oldRank;
111
- for (let j = this.currentIndex - 1; j >= 0; j--) {
112
- if (Team.compare(team, this.teams[j]) < 0) {
113
- this.newRank = this.teams[j].rank;
114
- } else {
115
- break;
116
- }
117
- }
118
- }
119
-
120
- this.currentOpIndex++;
121
-
122
- {
123
- let j = this.oldRank - 1;
124
-
125
- while (j >= 0 && Team.compare(this.teams[j], this.teams[j - 1]) < 0) {
126
- [this.teams[j], this.teams[j - 1]] = [this.teams[j - 1], this.teams[j]];
127
- this.teams[j].rank = j + 1;
128
- this.teams[j - 1].rank = j;
129
- j--;
130
- }
131
- }
132
- }
133
-
134
- rewind() {
135
- if (this.duringAnimation) {
136
- return;
137
- }
138
-
139
- if (this.currentOpIndex < 1) {
140
- return;
141
- }
142
-
143
- this.currentOpIndex--;
144
-
145
- const op = this.operations[this.currentOpIndex];
146
- const pIx = op.problemIx;
147
- const teamId = op.team.id;
148
- const team = this.teamsMap.get(teamId) as Team;
149
-
150
- team.problemStatistics[pIx] = op.beforeTeamProblemStatistics;
151
- team.calcSolvedData(this.contest.options);
152
-
153
- this.currentProblemIndex = pIx;
154
- this.currentTeamId = teamId;
155
-
156
- {
157
- this.oldRank = team.rank;
158
- this.newRank = this.oldRank;
159
- for (let j = this.currentIndex + 1; j <= this.maxIndex; j++) {
160
- if (Team.compare(team, this.teams[j]) > 0) {
161
- this.newRank = this.teams[j].rank;
162
- } else {
163
- break;
164
- }
165
- }
166
- }
167
-
168
- {
169
- let j = this.oldRank - 1;
170
- let newIndex = j;
171
-
172
- while (j < this.maxIndex && Team.compare(this.teams[j], this.teams[j + 1]) > 0) {
173
- [this.teams[j], this.teams[j + 1]] = [this.teams[j + 1], this.teams[j]];
174
- this.teams[j].rank = j + 1;
175
- this.teams[j + 1].rank = j + 2;
176
- newIndex = j + 1;
177
- j++;
178
- }
179
-
180
- this.currentIndex = newIndex;
181
- }
182
- }
183
- }