Skip to content

Commit 158468a

Browse files
authored
Merge pull request #1446 from AtCoder-NoviSteps/#1445
✨ Enable to import contests for Trie tree (#1445)
2 parents 6442d3a + 75fb994 commit 158468a

File tree

3 files changed

+66
-29
lines changed

3 files changed

+66
-29
lines changed

src/lib/types/contest.ts

+16
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,19 @@ export const ContestType: { [key in ContestTypeOrigin]: key } = {
4747

4848
// Re-exporting the original type with the original name.
4949
export type ContestType = ContestTypeOrigin;
50+
51+
/**
52+
* Represents a mapping of contest IDs to contest names.
53+
*
54+
* @interface ContestPrefix
55+
* @property {string} [key] - The contest ID.
56+
* @property {string} [key: string] - The contest name associated with the contest ID.
57+
* @example
58+
* {
59+
* "abc001": "AtCoder Beginner Contest 001",
60+
* "arc123": "AtCoder Regular Contest 123"
61+
* }
62+
*/
63+
export interface ContestPrefix {
64+
[key: string]: string;
65+
}

src/lib/utils/contest.ts

+42-29
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ContestType } from '$lib/types/contest';
1+
import { ContestType, type ContestPrefix } from '$lib/types/contest';
22

33
// See:
44
// https://github.com/kenkoooo/AtCoderProblems/blob/master/atcoder-problems-frontend/src/utils/ContestClassifier.ts
@@ -55,36 +55,15 @@ export const classifyContest = (contest_id: string) => {
5555
return ContestType.MATH_AND_ALGORITHM;
5656
}
5757

58-
// HACK: 2024年10月上旬時点では、以下のコンテストが該当。
59-
// Note: 対象コンテストが増えた場合は、判定条件を見直す必要がある。
60-
if (contest_id === 'tenka1-2018') {
58+
if (arcLikePrefixes.has(contest_id)) {
6159
return ContestType.ARC_LIKE;
6260
}
6361

64-
// ・CODE FESTIVAL 2017 qual
65-
// ・CODE FESTIVAL 2017 Final
66-
const prefixForAgcLike = ['code-festival-2017-qual', 'cf17-final'];
67-
68-
if (prefixForAgcLike.some((prefix) => contest_id.startsWith(prefix))) {
62+
if (agcLikePrefixes.some((prefix) => contest_id.startsWith(prefix))) {
6963
return ContestType.AGC_LIKE;
7064
}
7165

72-
// ・Chokudai SpeedRun
73-
// ・CODE FESTIVAL 2014 決勝
74-
// ・Donutsプロコンチャレンジ
75-
// ・MUJIN Programming Challenge 2016
76-
// ・COLOCON
77-
// ・GigaCode
78-
const prefixForOthers = [
79-
'chokudai_S',
80-
'code-festival-2014-final',
81-
'donuts',
82-
'mujin-pc-2016',
83-
'colopl',
84-
'gigacode',
85-
];
86-
87-
if (prefixForOthers.some((prefix) => contest_id.startsWith(prefix))) {
66+
if (atCoderOthersPrefixes.some((prefix) => contest_id.startsWith(prefix))) {
8867
return ContestType.OTHERS;
8968
}
9069

@@ -99,18 +78,52 @@ export const classifyContest = (contest_id: string) => {
9978
return null;
10079
};
10180

102-
export const AOJ_COURSES = {
81+
// HACK: As of early November 2024, the following contests are applicable.
82+
// Note: The classification logic may need to be revised when new contests are added.
83+
const ARC_LIKE: ContestPrefix = {
84+
'tenka1-2018': 'Tenka1 Programmer Contest 2018',
85+
} as const;
86+
const arcLikePrefixes = new Set(getContestPrefixes(ARC_LIKE));
87+
88+
const AGC_LIKE: ContestPrefix = {
89+
'code-festival-2016-qual': 'CODE FESTIVAL 2016 qual',
90+
'code-festival-2017-qual': 'CODE FESTIVAL 2017 qual',
91+
'cf17-final': 'CODE FESTIVAL 2017 final',
92+
} as const;
93+
const agcLikePrefixes = getContestPrefixes(AGC_LIKE);
94+
95+
const ATCODER_OTHERS: ContestPrefix = {
96+
chokudai_S: 'Chokudai SpeedRun',
97+
'code-festival-2014-final': 'Code Festival 2014 決勝',
98+
donuts: 'Donutsプロコンチャレンジ',
99+
'mujin-pc-2016': 'Mujin Programming Challenge 2016',
100+
'tenka1-2016-final': '天下一プログラマーコンテスト2016本戦',
101+
colopl: 'COLOCON',
102+
gigacode: 'GigaCode',
103+
} as const;
104+
const atCoderOthersPrefixes = getContestPrefixes(ATCODER_OTHERS);
105+
106+
// AIZU ONLINE JUDGE AOJ Courses
107+
export const AOJ_COURSES: ContestPrefix = {
103108
ITP1: 'プログラミング入門',
104109
ALDS1: 'アルゴリズムとデータ構造入門',
105110
ITP2: 'プログラミング応用',
106111
DPL: '組み合わせ最適化',
107112
} as const;
108113

114+
export function getPrefixForAojCourses() {
115+
return getContestPrefixes(AOJ_COURSES);
116+
}
117+
109118
const aojCoursePrefixes = new Set(getPrefixForAojCourses()); // For O(1) lookups
110119

111-
// AIZU ONLINE JUDGE AOJ Courses
112-
export function getPrefixForAojCourses() {
113-
return Object.keys(AOJ_COURSES);
120+
/**
121+
* Extracts contest prefixes (keys) from a contest prefix object.
122+
* @param contestPrefixes - Object mapping contest IDs to their display names
123+
* @returns Array of contest prefix strings
124+
*/
125+
export function getContestPrefixes(contestPrefixes: Record<string, string>) {
126+
return Object.keys(contestPrefixes);
114127
}
115128

116129
// priority: 0 (High) - 18 (Low)

src/test/lib/utils/test_cases/contest_type.ts

+8
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ export const arcLike = [
161161
];
162162

163163
export const agcLike = [
164+
createTestCaseForContestType('CODE FESTIVAL 2016 qual B')({
165+
contestId: 'code-festival-2016-qualb',
166+
expected: ContestType.AGC_LIKE,
167+
}),
164168
createTestCaseForContestType('CODE FESTIVAL 2017 qual A')({
165169
contestId: 'code-festival-2017-quala',
166170
expected: ContestType.AGC_LIKE,
@@ -204,6 +208,10 @@ export const atCoderOthers = [
204208
contestId: 'mujin-pc-2016',
205209
expected: ContestType.OTHERS,
206210
}),
211+
createTestCaseForContestType('天下一プログラマーコンテスト2016本戦')({
212+
contestId: 'tenka1-2016-final',
213+
expected: ContestType.OTHERS,
214+
}),
207215
createTestCaseForContestType('COLOCON 2018 qual')({
208216
contestId: 'colopl2018-qual',
209217
expected: ContestType.OTHERS,

0 commit comments

Comments
 (0)