Skip to content

Commit 2b33de5

Browse files
committed
:docs: Improve AtCoder university contest labels (#1526)
1 parent 5352890 commit 2b33de5

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

src/lib/utils/contest.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const AGC_LIKE: ContestPrefix = {
108108
} as const;
109109
const agcLikePrefixes = getContestPrefixes(AGC_LIKE);
110110

111-
// HACK: As of early November 2024, only UTPC is included.
111+
// HACK: As of November 2024, UTPC, TTPC and TUPC are included.
112112
// More university contests may be added in the future.
113113
/**
114114
* Maps university contest ID prefixes to their display names.
@@ -190,7 +190,7 @@ export function getContestPrefixes(contestPrefixes: Record<string, string>) {
190190
}
191191

192192
/**
193-
* Contest type priorities (0 = Highest, 19 = Lowest)
193+
* Contest type priorities (0 = Highest, 20 = Lowest)
194194
*
195195
* Priority assignment rationale:
196196
* - Educational contests (0-10): ABS, ABC, APG4B, etc.
@@ -262,7 +262,23 @@ export function getContestPriority(contestId: string): number {
262262
*/
263263
const regexForAxc = /^(abc|arc|agc)(\d{3})/i;
264264

265+
/**
266+
* Regular expression to match AtCoder University contest identifiers.
267+
*
268+
* The pattern matches strings that:
269+
* - Start with either "ut", "tt", or "tu"
270+
* - Followed by "pc"
271+
* - End with exactly year (four digits)
272+
*
273+
* Example matches:
274+
* - "utpc2014"
275+
* - "ttpc2022"
276+
* - "tupc2023"
277+
*/
278+
const regexForAtCoderUniversity = /^(ut|tt|tu)(pc)(\d{4})/;
279+
265280
export const getContestNameLabel = (contestId: string) => {
281+
// AtCoder
266282
if (regexForAxc.exec(contestId)) {
267283
return contestId.replace(
268284
regexForAxc,
@@ -298,10 +314,15 @@ export const getContestNameLabel = (contestId: string) => {
298314
return 'アルゴリズムと数学';
299315
}
300316

317+
if (atCoderUniversityPrefixes.some((prefix) => contestId.startsWith(prefix))) {
318+
return getAtCoderUniversityContestLabel(contestId);
319+
}
320+
301321
if (contestId.startsWith('chokudai_S')) {
302322
return contestId.replace('chokudai_S', 'Chokudai SpeedRun ');
303323
}
304324

325+
// AIZU ONLINE JUDGE
305326
if (aojCoursePrefixes.has(contestId)) {
306327
return 'AOJ Courses';
307328
}
@@ -317,6 +338,24 @@ export const getContestNameLabel = (contestId: string) => {
317338
return contestId.toUpperCase();
318339
};
319340

341+
/**
342+
* Generates a formatted contest label for AtCoder University contests.
343+
*
344+
* This function takes a contest ID string and replaces parts of it using a regular expression
345+
* to generate a formatted label. The label is constructed by converting the contest type and
346+
* common part to uppercase and appending the contest year.
347+
*
348+
* @param contestId - The ID of the contest to format (ex: utpc2023).
349+
* @returns The formatted contest label (ex: UTPC 2023).
350+
*/
351+
export function getAtCoderUniversityContestLabel(contestId: string): string {
352+
return contestId.replace(
353+
regexForAtCoderUniversity,
354+
(_, contestType, common, contestYear) =>
355+
`${(contestType + common).toUpperCase()} ${contestYear}`,
356+
);
357+
}
358+
320359
/**
321360
* Maps PCK contest type abbreviations to their Japanese translations.
322361
*

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createTestCase, zip } from '../../common/test_helpers';
2+
import { getAtCoderUniversityContestLabel } from '$lib/utils/contest';
23

34
export type TestCaseForContestNameAndTaskIndex = {
45
contestId: string;
@@ -300,11 +301,11 @@ const generateUniversityTestCases = (
300301
): { name: string; value: TestCaseForContestNameAndTaskIndex }[] => {
301302
return zip(contestIds, taskIndices).map(([contestId, taskIndex]) => {
302303
const testCase = createTestCaseForContestNameAndTaskIndex(
303-
`${contestId.toUpperCase()} ${taskIndex}`,
304+
`${getAtCoderUniversityContestLabel(contestId)} ${taskIndex}`,
304305
)({
305306
contestId: `${contestId}`,
306307
taskTableIndex: taskIndex,
307-
expected: `${contestId.toUpperCase()} - ${taskIndex}`,
308+
expected: `${getAtCoderUniversityContestLabel(contestId)} - ${taskIndex}`,
308309
});
309310

310311
return testCase;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ const generateUtpcTestCases = (
257257
return years.map((year) => {
258258
const testCase = createTestCaseForContestNameLabel(`UTPC ${year}`)({
259259
contestId: `utpc${year}`,
260-
expected: `UTPC${year}`,
260+
expected: `UTPC ${year}`,
261261
});
262262

263263
return testCase;
@@ -269,7 +269,7 @@ const generateTtpcTestCases = (
269269
return years.map((year) => {
270270
const testCase = createTestCaseForContestNameLabel(`TTPC ${year}`)({
271271
contestId: `ttpc${year}`,
272-
expected: `TTPC${year}`,
272+
expected: `TTPC ${year}`,
273273
});
274274

275275
return testCase;
@@ -281,7 +281,7 @@ const generateTupcTestCases = (
281281
return years.map((year) => {
282282
const testCase = createTestCaseForContestNameLabel(`TUPC ${year}`)({
283283
contestId: `tupc${year}`,
284-
expected: `TUPC${year}`,
284+
expected: `TUPC ${year}`,
285285
});
286286

287287
return testCase;

0 commit comments

Comments
 (0)