Skip to content

Commit c9b92c8

Browse files
authored
Merge pull request #1336 from AtCoder-NoviSteps/#1335
✨ Add AXC-like contests (#1335)
2 parents f697fdf + 193bd80 commit c9b92c8

File tree

6 files changed

+98
-12
lines changed

6 files changed

+98
-12
lines changed

prisma/ERD.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ TESSOKU_BOOK TESSOKU_BOOK
2222
MATH_AND_ALGORITHM MATH_AND_ALGORITHM
2323
ARC ARC
2424
AGC AGC
25+
ABC_LIKE ABC_LIKE
26+
ARC_LIKE ARC_LIKE
27+
AGC_LIKE AGC_LIKE
2528
OTHERS OTHERS
2629
}
2730
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- AlterEnum
2+
-- This migration adds more than one value to an enum.
3+
-- With PostgreSQL versions 11 and earlier, this is not possible
4+
-- in a single migration. This can be worked around by creating
5+
-- multiple migrations, each migration adding only one value to
6+
-- the enum.
7+
8+
9+
ALTER TYPE "ContestType" ADD VALUE 'ABC_LIKE';
10+
ALTER TYPE "ContestType" ADD VALUE 'ARC_LIKE';
11+
ALTER TYPE "ContestType" ADD VALUE 'AGC_LIKE';

prisma/schema.prisma

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ enum ContestType {
217217
MATH_AND_ALGORITHM // アルゴリズムと数学
218218
ARC // AtCoder Regular Contest
219219
AGC // AtCoder Grand Contest
220+
ABC_LIKE // AtCoder Beginner Contest (ABC) 相当のコンテスト
221+
ARC_LIKE // AtCoder Regular Contest (ARC) 相当のコンテスト
222+
AGC_LIKE // AtCoder Grand Contest (AGC) 相当のコンテスト
220223
OTHERS // その他
221224
}
222225

src/lib/types/contest.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ export const ContestType: { [key in ContestTypeOrigin]: key } = {
1515
MATH_AND_ALGORITHM: 'MATH_AND_ALGORITHM', // アルゴリズムと数学
1616
ARC: 'ARC', // AtCoder Regular Contest
1717
AGC: 'AGC', // AtCoder Grand Contest
18+
ABC_LIKE: 'ABC_LIKE', // AtCoder Beginner Contest (ABC) 相当のコンテスト
19+
ARC_LIKE: 'ARC_LIKE', // AtCoder Regular Contest (ARC) 相当のコンテスト
20+
AGC_LIKE: 'AGC_LIKE', // AtCoder Grand Contest (AGC) 相当のコンテスト
1821
OTHERS: 'OTHERS',
1922
} as const;
2023

src/lib/utils/contest.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,22 @@ export const classifyContest = (contest_id: string) => {
5656
return ContestType.MATH_AND_ALGORITHM;
5757
}
5858

59-
// HACK: 2024年9月下旬時点では、「Chokudai SpeedRun」と「Donutsプロコンチャレンジ」「COLOCON」「GigaCode」のみ該当。
60-
// 対象コンテストが増えた場合は、判定条件を見直す必要がある。
61-
const prefixes = ['chokudai_S', 'donuts', 'colopl', 'gigacode'];
59+
// HACK: 2024年10月上旬時点では、以下のコンテストが該当。
60+
// Note: 対象コンテストが増えた場合は、判定条件を見直す必要がある。
61+
if (contest_id === 'tenka1-2018') {
62+
return ContestType.ARC_LIKE;
63+
}
64+
65+
if (contest_id.startsWith('code-festival-2017-qual')) {
66+
return ContestType.AGC_LIKE;
67+
}
68+
69+
// ・Chokudai SpeedRun
70+
// ・CODE FESTIVAL 2014 決勝
71+
// ・Donutsプロコンチャレンジ
72+
// ・COLOCON
73+
// ・GigaCode
74+
const prefixes = ['chokudai_S', 'code-festival-2014-final', 'donuts', 'colopl', 'gigacode'];
6275

6376
if (prefixes.some((prefix) => contest_id.startsWith(prefix))) {
6477
return ContestType.OTHERS;
@@ -67,7 +80,7 @@ export const classifyContest = (contest_id: string) => {
6780
return null;
6881
};
6982

70-
// priority: 0 (High) - 13 (Low)
83+
// priority: 0 (High) - 16 (Low)
7184
// HACK: ARC、AGCの優先順位は暫定版
7285
//
7386
// See:
@@ -86,7 +99,10 @@ export const contestTypePriorities: Map<ContestType, number> = new Map([
8699
[ContestType.MATH_AND_ALGORITHM, 10],
87100
[ContestType.ARC, 11],
88101
[ContestType.AGC, 12],
89-
[ContestType.OTHERS, 13],
102+
[ContestType.ABC_LIKE, 13],
103+
[ContestType.ARC_LIKE, 14],
104+
[ContestType.AGC_LIKE, 15],
105+
[ContestType.OTHERS, 16],
90106
]);
91107

92108
export function getContestPriority(contestId: string): number {

src/test/lib/utils/contest.test.ts

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ type TestCaseForContestNameAndTaskIndex = {
3333
type TestCasesForContestNameAndTaskIndex = TestCaseForContestNameAndTaskIndex[];
3434

3535
describe('Contest', () => {
36-
// TODO: Add ARC and AOI.
36+
// TODO: Add AOI.
3737
describe('classify contest', () => {
3838
test('when contest_id is ABS', () => {
3939
expect(classifyContest('abs')).toEqual(ContestType.ABS);
4040
});
4141

42-
describe('when contest_id contains ABC', () => {
42+
describe('when contest_id contains abc', () => {
4343
const testCases = [
4444
{ contestId: 'abc001', expected: ContestType.ABC },
4545
{ contestId: 'abc002', expected: ContestType.ABC },
@@ -159,6 +159,26 @@ describe('Contest', () => {
159159
});
160160
});
161161

162+
describe('when contest_id means arc-like', () => {
163+
const testCases = [{ contestId: 'tenka1-2018', expected: ContestType.ARC_LIKE }];
164+
165+
runTests('classifyContest', testCases, ({ contestId, expected }: TestCaseForContestType) => {
166+
expect(classifyContest(contestId)).toEqual(expected);
167+
});
168+
});
169+
170+
describe('when contest_id means agc-like', () => {
171+
const testCases = [
172+
{ contestId: 'code-festival-2017-quala', expected: ContestType.AGC_LIKE },
173+
{ contestId: 'code-festival-2017-qualb', expected: ContestType.AGC_LIKE },
174+
{ contestId: 'code-festival-2017-qualc', expected: ContestType.AGC_LIKE },
175+
];
176+
177+
runTests('classifyContest', testCases, ({ contestId, expected }: TestCaseForContestType) => {
178+
expect(classifyContest(contestId)).toEqual(expected);
179+
});
180+
});
181+
162182
describe('when contest_id contains chokudai_S', () => {
163183
const testCases = [
164184
{ contestId: 'chokudai_S001', expected: ContestType.OTHERS },
@@ -170,8 +190,9 @@ describe('Contest', () => {
170190
});
171191
});
172192

173-
describe('when contest_id contains donuts, colopl and gigacode', () => {
193+
describe('when contest_id contains code-festival-2014-final, donuts, colopl and gigacode', () => {
174194
const testCases = [
195+
{ contestId: 'code-festival-2014-final', expected: ContestType.OTHERS },
175196
{ contestId: 'donuts-live2014', expected: ContestType.OTHERS },
176197
{ contestId: 'donuts-2015', expected: ContestType.OTHERS },
177198
{ contestId: 'colopl2018-qual', expected: ContestType.OTHERS },
@@ -194,11 +215,11 @@ describe('Contest', () => {
194215
});
195216

196217
describe('get contest priority', () => {
197-
test('when contest_id is ABS', () => {
218+
test('when contest_id is abs', () => {
198219
expect(getContestPriority('abs')).toEqual(contestTypePriorities.get(ContestType.ABS));
199220
});
200221

201-
describe('when contest_id contains ABC', () => {
222+
describe('when contest_id contains abc', () => {
202223
const testCases = [
203224
{ contestId: 'abc001', expected: ContestType.ABC },
204225
{ contestId: 'abc002', expected: ContestType.ABC },
@@ -346,6 +367,34 @@ describe('Contest', () => {
346367
);
347368
});
348369

370+
describe('when contest_id means arc-like', () => {
371+
const testCases = [{ contestId: 'tenka1-2018', expected: ContestType.ARC_LIKE }];
372+
373+
runTests(
374+
'getContestPriority',
375+
testCases,
376+
({ contestId, expected }: TestCaseForContestType) => {
377+
expect(getContestPriority(contestId)).toEqual(contestTypePriorities.get(expected));
378+
},
379+
);
380+
});
381+
382+
describe('when contest_id means agc-like', () => {
383+
const testCases = [
384+
{ contestId: 'code-festival-2017-quala', expected: ContestType.AGC_LIKE },
385+
{ contestId: 'code-festival-2017-qualb', expected: ContestType.AGC_LIKE },
386+
{ contestId: 'code-festival-2017-qualc', expected: ContestType.AGC_LIKE },
387+
];
388+
389+
runTests(
390+
'getContestPriority',
391+
testCases,
392+
({ contestId, expected }: TestCaseForContestType) => {
393+
expect(getContestPriority(contestId)).toEqual(contestTypePriorities.get(expected));
394+
},
395+
);
396+
});
397+
349398
describe('when contest_id contains chokudai_S', () => {
350399
const testCases = [
351400
{ contestId: 'chokudai_S001', expected: ContestType.OTHERS },
@@ -361,8 +410,9 @@ describe('Contest', () => {
361410
);
362411
});
363412

364-
describe('when contest_id contains donuts, colopl and gigacode', () => {
413+
describe('when contest_id contains code-festival-2014-final, donuts, colopl and gigacode', () => {
365414
const testCases = [
415+
{ contestId: 'code-festival-2014-final', expected: ContestType.OTHERS },
366416
{ contestId: 'donuts-live2014', expected: ContestType.OTHERS },
367417
{ contestId: 'donuts-2015', expected: ContestType.OTHERS },
368418
{ contestId: 'colopl2018-qual', expected: ContestType.OTHERS },
@@ -405,7 +455,7 @@ describe('Contest', () => {
405455
});
406456

407457
describe('get contest name label', () => {
408-
describe('when contest_id contains ABC', () => {
458+
describe('when contest_id contains abc', () => {
409459
const testCases = [
410460
{ contestId: 'abc001', expected: 'ABC001' },
411461
{ contestId: 'abc002', expected: 'ABC002' },

0 commit comments

Comments
 (0)