File size: 2,917 Bytes
5f7afef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from __future__ import annotations
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field

from codestar.problems.loader import repo

router = APIRouter(prefix="/api/problems", tags=["Problems"])


class ProblemListItem(BaseModel):
    slug: str
    title: str
    difficulty: str
    difficulty_breakdown: Optional[Dict[str, int]] = None
    category: str
    tags: List[str]
    time_limit: float
    memory_limit_mb: int
    is_featured: bool = False


class ProblemDetail(BaseModel):
    slug: str
    title: str
    difficulty: str
    difficulty_breakdown: Optional[Dict[str, int]] = None
    category: str
    tags: List[str]
    description_md: str
    entry_point: str
    starter_code: str
    reference_code: Optional[str] = None
    time_limit: float
    memory_limit_mb: int
    atol: float
    rtol: float
    is_featured: bool = False
    editorial_md: Optional[str] = None
    test_cases: List[Dict[str, Any]] = Field(default_factory=list)


@router.get("", response_model=List[ProblemListItem])
def list_problems(category: Optional[str] = None):
    return repo.get_list_items(category)


@router.get("/random", response_model=ProblemListItem)
def get_random_problem(category: Optional[str] = None):
    import random
    items = repo.get_list_items(category)
    if not items:
        raise HTTPException(status_code=404, detail="No problems found")
    return random.choice(items)


@router.get("/daily")
def get_daily_challenge():
    import datetime
    import hashlib
    today_str = datetime.date.today().isoformat()
    featured = repo.get_list_items("featured")
    pool = featured if featured else repo.get_list_items()
    if not pool:
        raise HTTPException(status_code=404, detail="No problems found")
    hash_val = int(hashlib.md5(today_str.encode("utf-8")).hexdigest(), 16)
    picked = pool[hash_val % len(pool)]
    return {
        "date": today_str,
        "problem": picked,
    }


@router.get("/{slug}", response_model=ProblemDetail)
def get_problem(slug: str):
    problem = repo.get(slug)
    if not problem:
        raise HTTPException(status_code=404, detail=f"Problem '{slug}' not found")
    return ProblemDetail(
        slug=problem.slug,
        title=problem.title,
        difficulty=problem.difficulty,
        difficulty_breakdown=repo.get_difficulty_breakdown(slug),
        category=problem.category,
        tags=problem.tags,
        description_md=problem.description_md,
        entry_point=problem.entry_point,
        starter_code=problem.starter_code,
        reference_code=problem.reference_code,
        time_limit=problem.time_limit,
        memory_limit_mb=problem.memory_limit_mb,
        atol=problem.atol,
        rtol=problem.rtol,
        is_featured=problem.is_featured,
        editorial_md=problem.editorial_md,
        test_cases=repo.get_test_cases(slug),
    )