Skip to content

Commit 04ebb77

Browse files
authored
Merge pull request #2999 from AtCoder-NoviSteps/create_joi_table
Create JOI second qual and semi-final round table
2 parents 7e128ea + 541317c commit 04ebb77

3 files changed

Lines changed: 384 additions & 7 deletions

File tree

src/lib/types/contest_table_provider.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ export const TESSOKU_SECTIONS = {
8484
CHALLENGES: 'challenges',
8585
} as const;
8686

87+
export const JOI_SECOND_QUAL_ROUND_SECTIONS = {
88+
'2020Onwards': '2020Onwards',
89+
from2006To2019: 'from2006To2019',
90+
} as const;
91+
92+
export const JOI_FINAL_ROUND_SECTIONS = {
93+
semiFinal: 'semiFinal',
94+
} as const;
95+
8796
/**
8897
* Represents a two-dimensional table of contest results.
8998
*

src/lib/utils/contest_table_provider.ts

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
type ContestTableDisplayConfig,
77
type ProviderKey,
88
TESSOKU_SECTIONS,
9+
JOI_SECOND_QUAL_ROUND_SECTIONS,
10+
JOI_FINAL_ROUND_SECTIONS,
911
} from '$lib/types/contest_table_provider';
1012
import { ContestType } from '$lib/types/contest';
1113
import type { TaskResults, TaskResult } from '$lib/types/task';
@@ -834,6 +836,126 @@ export class JOIFirstQualRoundProvider extends ContestTableProviderBase {
834836
}
835837
}
836838

839+
const regexForJoiSecondQualRound = /^(joi)(\d{4})(yo2)$/i;
840+
841+
export class JOISecondQualRound2020OnwardsProvider extends ContestTableProviderBase {
842+
constructor(contestType: ContestType) {
843+
super(contestType, JOI_SECOND_QUAL_ROUND_SECTIONS['2020Onwards']);
844+
}
845+
846+
protected setFilterCondition(): (taskResult: TaskResult) => boolean {
847+
return (taskResult: TaskResult) => {
848+
if (classifyContest(taskResult.contest_id) !== this.contestType) {
849+
return false;
850+
}
851+
852+
return regexForJoiSecondQualRound.test(taskResult.contest_id);
853+
};
854+
}
855+
856+
getMetadata(): ContestTableMetaData {
857+
return {
858+
title: 'JOI 二次予選',
859+
abbreviationName: 'joiSecondQualRound2020Onwards',
860+
};
861+
}
862+
863+
getDisplayConfig(): ContestTableDisplayConfig {
864+
return {
865+
isShownHeader: true,
866+
isShownRoundLabel: true,
867+
isShownTaskIndex: false,
868+
tableBodyCellsWidth: 'w-1/2 xs:w-1/3 sm:w-1/4 md:w-1/5 px-1 py-1',
869+
roundLabelWidth: 'xl:w-28',
870+
};
871+
}
872+
873+
getContestRoundLabel(contestId: string): string {
874+
const contestNameLabel = getContestNameLabel(contestId);
875+
return contestNameLabel.replace('JOI 二次予選 ', '');
876+
}
877+
}
878+
879+
const regexForJoiQualRound = /^(joi)(\d{4})(yo)$/i;
880+
881+
export class JOIQualRoundFrom2006To2019Provider extends ContestTableProviderBase {
882+
constructor(contestType: ContestType) {
883+
super(contestType, JOI_SECOND_QUAL_ROUND_SECTIONS.from2006To2019);
884+
}
885+
886+
protected setFilterCondition(): (taskResult: TaskResult) => boolean {
887+
return (taskResult: TaskResult) => {
888+
if (classifyContest(taskResult.contest_id) !== this.contestType) {
889+
return false;
890+
}
891+
892+
return regexForJoiQualRound.test(taskResult.contest_id);
893+
};
894+
}
895+
896+
getMetadata(): ContestTableMetaData {
897+
return {
898+
title: 'JOI 予選',
899+
abbreviationName: 'joiQualRoundFrom2006To2019',
900+
};
901+
}
902+
903+
getDisplayConfig(): ContestTableDisplayConfig {
904+
return {
905+
isShownHeader: true,
906+
isShownRoundLabel: true,
907+
isShownTaskIndex: false,
908+
tableBodyCellsWidth: 'w-1/2 xs:w-1/3 sm:w-1/4 md:w-1/5 lg:w-1/6 px-1 py-1',
909+
roundLabelWidth: 'xl:w-28',
910+
};
911+
}
912+
913+
getContestRoundLabel(contestId: string): string {
914+
const contestNameLabel = getContestNameLabel(contestId);
915+
return contestNameLabel.replace('JOI 予選 ', '');
916+
}
917+
}
918+
919+
const regexForJoiSemiFinalRound = /^(joi)(\d{4})(ho)$/i;
920+
921+
export class JOISemiFinalRoundProvider extends ContestTableProviderBase {
922+
constructor(contestType: ContestType) {
923+
super(contestType, JOI_FINAL_ROUND_SECTIONS.semiFinal);
924+
}
925+
926+
protected setFilterCondition(): (taskResult: TaskResult) => boolean {
927+
return (taskResult: TaskResult) => {
928+
if (classifyContest(taskResult.contest_id) !== this.contestType) {
929+
return false;
930+
}
931+
932+
return regexForJoiSemiFinalRound.test(taskResult.contest_id);
933+
};
934+
}
935+
936+
getMetadata(): ContestTableMetaData {
937+
return {
938+
title: 'JOI 本選',
939+
abbreviationName: 'joiSemiFinalRound',
940+
};
941+
}
942+
943+
getDisplayConfig(): ContestTableDisplayConfig {
944+
return {
945+
isShownHeader: true,
946+
isShownRoundLabel: true,
947+
isShownTaskIndex: false,
948+
tableBodyCellsWidth: 'w-1/2 xs:w-1/3 sm:w-1/4 md:w-1/5 px-1 py-1',
949+
roundLabelWidth: 'xl:w-28',
950+
};
951+
}
952+
953+
getContestRoundLabel(contestId: string): string {
954+
const contestNameLabel = getContestNameLabel(contestId);
955+
return contestNameLabel.replace('JOI 本選 ', '');
956+
}
957+
}
958+
837959
/**
838960
* A class that manages individual provider groups
839961
* Manages multiple ContestTableProviders as a single group,
@@ -1104,6 +1226,16 @@ export const prepareContestProviderPresets = () => {
11041226
buttonLabel: 'JOI 一次予選',
11051227
ariaLabel: 'Filter JOI First Qualifying Round',
11061228
}).addProvider(new JOIFirstQualRoundProvider(ContestType.JOI)),
1229+
1230+
JOISecondQualAndSemiFinalRound: () =>
1231+
new ContestTableProviderGroup(`JOI 二次予選・予選・本選`, {
1232+
buttonLabel: 'JOI 二次予選・予選・本選',
1233+
ariaLabel: 'Filter JOI Second Qual Round',
1234+
}).addProviders(
1235+
new JOISecondQualRound2020OnwardsProvider(ContestType.JOI),
1236+
new JOIQualRoundFrom2006To2019Provider(ContestType.JOI),
1237+
new JOISemiFinalRoundProvider(ContestType.JOI),
1238+
),
11071239
};
11081240
};
11091241

@@ -1125,6 +1257,7 @@ export const contestTableProviderGroups = {
11251257
dps: prepareContestProviderPresets().dps(), // Dynamic Programming (DP) Contests
11261258
aclPractice: prepareContestProviderPresets().AclPractice(),
11271259
joiFirstQualRound: prepareContestProviderPresets().JOIFirstQualRound(),
1260+
joiSecondQualAndSemiFinalRound: prepareContestProviderPresets().JOISecondQualAndSemiFinalRound(),
11281261
};
11291262

11301263
export type ContestTableProviderGroups = keyof typeof contestTableProviderGroups;

0 commit comments

Comments
 (0)