Skip to content

Commit

Permalink
Merge pull request #1345 from Eagle-Konbu/add-contest-type-button-to-…
Browse files Browse the repository at this point in the history
…virtual-contests

Add contest type button to virtual contests
  • Loading branch information
kenkoooo authored Oct 15, 2023
2 parents 5737038 + 4cc9649 commit 7eaec11
Showing 1 changed file with 66 additions and 0 deletions.
66 changes: 66 additions & 0 deletions atcoder-problems-frontend/src/components/ProblemSetGenerator.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Button,
ButtonGroup,
Col,
DropdownItem,
DropdownMenu,
Expand All @@ -15,11 +16,13 @@ import {
} from "reactstrap";
import React, { useState } from "react";
import {
useContests,
useMultipleUserSubmissions,
useProblemModelMap,
useProblems,
} from "../api/APIClient";
import Problem from "../interfaces/Problem";
import Contest from "../interfaces/Contest";
import { shuffleArray } from "../utils";
import {
ExcludeOption,
Expand All @@ -29,6 +32,7 @@ import {
getLastSolvedTimeMap,
getMaximumExcludeElapsedSecond,
} from "../utils/LastSolvedTime";
import { classifyContest } from "../utils/ContestClassifier";
import { isProblemModelWithDifficultyModel } from "../interfaces/ProblemModel";

interface Props {
Expand Down Expand Up @@ -90,13 +94,30 @@ export const ProblemSetGenerator: React.FC<Props> = (props) => {
);
const [excludeExperimental, setExcludeExperimental] = useState(false);
const [excludeOption, setExcludeOption] = useState<ExcludeOption>("Exclude");
const [contestTypeOption, setContestTypeOption] = useState({
ABC: true,
ARC: true,
AGC: true,
ABC_Like: true,
ARC_Like: true,
AGC_Like: true,
});
const [selectedPreset, setSelectedPreset] = useState(ABC_PRESET);
const problems = useProblems() ?? [];
const problemModels = useProblemModelMap();
const submissions =
useMultipleUserSubmissions(props.expectedParticipantUserIds).data ?? [];
const alreadySolvedProblemIds = new Set(submissions.map((s) => s.problem_id));
const lastSolvedTimeMap = getLastSolvedTimeMap(submissions);
const { data: contests } = useContests();

const contestTypeKeyToDisplayName = (key: string) => {
if (key.includes("Like")) {
return key.replace("_", "-");
} else {
return key;
}
};

return (
<Form className={"w-100"}>
Expand Down Expand Up @@ -142,6 +163,31 @@ export const ProblemSetGenerator: React.FC<Props> = (props) => {
</InputGroup>
</Col>
</FormGroup>
<FormGroup row>
<Col sm={6}>
<Label>Include / Exclude Contest Types</Label>
<InputGroup>
<ButtonGroup>
{Object.keys(contestTypeOption).map((contestType) => {
return (
<Button
key={contestType}
active={contestTypeOption[contestType] as boolean}
onClick={(): void => {
setContestTypeOption({
...contestTypeOption,
[contestType]: !contestTypeOption[contestType],
});
}}
>
{contestTypeKeyToDisplayName(contestType)}
</Button>
);
})}
</ButtonGroup>
</InputGroup>
</Col>
</FormGroup>
<FormGroup row>
<Col sm={6}>
<Label>Difficulty Adjustment Preset</Label>
Expand Down Expand Up @@ -278,6 +324,26 @@ export const ProblemSetGenerator: React.FC<Props> = (props) => {
});
}

let candidateContests: Contest[] = [];
Object.keys(contestTypeOption).forEach((contestType) => {
if (contestTypeOption[contestType]) {
const filteredContests = contests.filter((contest) => {
return (
contestTypeKeyToDisplayName(contestType) ===
classifyContest(contest)
);
});
candidateContests = candidateContests.concat(
filteredContests
);
}
});
candidateProblems = candidateProblems.filter((p) => {
return candidateContests
.map((contest) => contest.id)
.includes(p.problem.contest_id);
});

candidateProblems = candidateProblems.filter((p) => {
if (excludeOption === "Exclude submitted") {
return !alreadySolvedProblemIds.has(p.problem.id);
Expand Down

0 comments on commit 7eaec11

Please sign in to comment.