read the best solution for each task in contest #8
5 changed files with 82 additions and 1 deletions
|
@ -99,6 +99,15 @@ func (h *TesterHandlers) GetContest(c *fiber.Ctx, id int32) error {
|
||||||
return c.SendStatus(pkg.ToREST(err))
|
return c.SendStatus(pkg.ToREST(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var participantId int32 = 2
|
||||||
|
|
||||||
|
solutions, err := h.contestsUC.ReadBestSolutions(c.Context(), id, participantId)
|
||||||
|
|
||||||
|
m := make(map[int32]*models.Solution)
|
||||||
|
|
||||||
|
for i := 0; i < len(solutions); i++ {
|
||||||
|
m[solutions[i].TaskPosition] = solutions[i]
|
||||||
|
}
|
||||||
resp := testerv1.GetContestResponse{
|
resp := testerv1.GetContestResponse{
|
||||||
Contest: C2C(*contest),
|
Contest: C2C(*contest),
|
||||||
Tasks: make([]struct {
|
Tasks: make([]struct {
|
||||||
|
@ -108,11 +117,15 @@ func (h *TesterHandlers) GetContest(c *fiber.Ctx, id int32) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, task := range tasks {
|
for i, task := range tasks {
|
||||||
|
solution := testerv1.Solution{}
|
||||||
|
if sol, ok := m[task.Position]; ok {
|
||||||
|
solution = S2S(*sol)
|
||||||
|
}
|
||||||
resp.Tasks[i] = struct {
|
resp.Tasks[i] = struct {
|
||||||
Solution testerv1.Solution `json:"solution"`
|
Solution testerv1.Solution `json:"solution"`
|
||||||
Task testerv1.TasksListItem `json:"task"`
|
Task testerv1.TasksListItem `json:"task"`
|
||||||
}{
|
}{
|
||||||
Solution: testerv1.Solution{},
|
Solution: solution,
|
||||||
Task: TLI2TLI(*task),
|
Task: TLI2TLI(*task),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,4 +49,5 @@ type ContestRepository interface {
|
||||||
ListSolutions(ctx context.Context, filter models.SolutionsFilter) (*models.SolutionsList, error)
|
ListSolutions(ctx context.Context, filter models.SolutionsFilter) (*models.SolutionsList, error)
|
||||||
ReadTask(ctx context.Context, id int32) (*models.Task, error)
|
ReadTask(ctx context.Context, id int32) (*models.Task, error)
|
||||||
ReadMonitor(ctx context.Context, id int32) (*models.Monitor, error)
|
ReadMonitor(ctx context.Context, id int32) (*models.Monitor, error)
|
||||||
|
ReadBestSolutions(ctx context.Context, contestId int32, participantId int32) ([]*models.Solution, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -626,3 +626,65 @@ func (r *ContestRepository) ReadMonitor(ctx context.Context, contestId int32) (*
|
||||||
|
|
||||||
return &monitor, nil
|
return &monitor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// state=5 - AC
|
||||||
|
readBestSolutions = `
|
||||||
|
WITH contest_tasks AS (
|
||||||
|
SELECT t.id AS task_id,
|
||||||
|
t.position AS task_position,
|
||||||
|
t.contest_id,
|
||||||
|
t.problem_id,
|
||||||
|
t.created_at,
|
||||||
|
t.updated_at,
|
||||||
|
p.title AS task_title,
|
||||||
|
c.title AS contest_title
|
||||||
|
FROM tasks t
|
||||||
|
LEFT JOIN problems p ON p.id = t.problem_id
|
||||||
|
LEFT JOIN contests c ON c.id = t.contest_id
|
||||||
|
WHERE t.contest_id = ?
|
||||||
|
),
|
||||||
|
best_solutions AS (
|
||||||
|
SELECT DISTINCT ON (s.task_id)
|
||||||
|
*
|
||||||
|
FROM solutions s
|
||||||
|
WHERE s.participant_id = ?
|
||||||
|
ORDER BY s.task_id, s.score DESC, s.created_at DESC
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
s.id,
|
||||||
|
s.participant_id,
|
||||||
|
p.name AS participant_name,
|
||||||
|
s.solution,
|
||||||
|
s.state,
|
||||||
|
s.score,
|
||||||
|
s.penalty,
|
||||||
|
s.time_stat,
|
||||||
|
s.memory_stat,
|
||||||
|
s.language,
|
||||||
|
ct.task_id,
|
||||||
|
ct.task_position,
|
||||||
|
ct.task_title,
|
||||||
|
ct.contest_id,
|
||||||
|
ct.contest_title,
|
||||||
|
s.updated_at,
|
||||||
|
s.created_at
|
||||||
|
FROM contest_tasks ct
|
||||||
|
LEFT JOIN best_solutions s ON s.task_id = ct.task_id
|
||||||
|
LEFT JOIN participants p ON p.id = s.participant_id WHERE s.id IS NOT NULL
|
||||||
|
ORDER BY ct.task_position
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r *ContestRepository) ReadBestSolutions(ctx context.Context, contestId int32, participantId int32) ([]*models.Solution, error) {
|
||||||
|
const op = "ContestRepository.ReadBestSolutions"
|
||||||
|
var solutions []*models.Solution
|
||||||
|
query := r.db.Rebind(readBestSolutions)
|
||||||
|
err := r.db.SelectContext(ctx, &solutions, query, contestId, participantId)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, handlePgErr(err, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
return solutions, nil
|
||||||
|
}
|
||||||
|
|
|
@ -31,4 +31,5 @@ type ContestUseCase interface {
|
||||||
ListSolutions(ctx context.Context, filter models.SolutionsFilter) (*models.SolutionsList, error)
|
ListSolutions(ctx context.Context, filter models.SolutionsFilter) (*models.SolutionsList, error)
|
||||||
ReadTask(ctx context.Context, id int32) (*models.Task, error)
|
ReadTask(ctx context.Context, id int32) (*models.Task, error)
|
||||||
ReadMonitor(ctx context.Context, id int32) (*models.Monitor, error)
|
ReadMonitor(ctx context.Context, id int32) (*models.Monitor, error)
|
||||||
|
ReadBestSolutions(ctx context.Context, contestId int32, participantId int32) ([]*models.Solution, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,3 +85,7 @@ func (uc *ContestUseCase) ReadTask(ctx context.Context, id int32) (*models.Task,
|
||||||
func (uc *ContestUseCase) ReadMonitor(ctx context.Context, contestId int32) (*models.Monitor, error) {
|
func (uc *ContestUseCase) ReadMonitor(ctx context.Context, contestId int32) (*models.Monitor, error) {
|
||||||
return uc.contestRepo.ReadMonitor(ctx, contestId)
|
return uc.contestRepo.ReadMonitor(ctx, contestId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (uc *ContestUseCase) ReadBestSolutions(ctx context.Context, contestId int32, participantId int32) ([]*models.Solution, error) {
|
||||||
|
return uc.contestRepo.ReadBestSolutions(ctx, contestId, participantId)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue