Skip to content

Commit f5547c3

Browse files
Merge pull request #41 from ContextLab/copilot/add-automatic-solver
Add GPT-5-mini auto-solver for daily LeetCode problems
2 parents fb14afe + 6489dee commit f5547c3

File tree

3 files changed

+250
-0
lines changed

3 files changed

+250
-0
lines changed

.github/workflows/auto_solver.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Auto-solve Daily LeetCode Problem
2+
3+
on:
4+
schedule:
5+
- cron: '1 0 * * *' # Runs daily at 00:01 UTC (1 minute after daily problems are released)
6+
workflow_dispatch: # Allows for manual triggering
7+
8+
jobs:
9+
auto-solve:
10+
runs-on: ubuntu-latest
11+
if: github.repository_owner == 'ContextLab' # only run if on the ContextLab (source) repository!
12+
13+
permissions:
14+
contents: write # Required to push commits back to the repository
15+
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v3
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v4
22+
with:
23+
python-version: '3.11'
24+
25+
- name: Install dependencies
26+
run: |
27+
python -m pip install --upgrade pip
28+
pip install requests openai
29+
30+
- name: Run auto-solver
31+
env:
32+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
33+
run: |
34+
python auto_solver.py
35+
36+
- name: Commit and push changes
37+
uses: stefanzweifel/git-auto-commit-action@v4
38+
with:
39+
commit_message: "Auto-solve daily LeetCode problem using GPT-5-mini"
40+
branch: main
41+
file_pattern: problems/*/gpt5-mini.md

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ Each day (ideally) we'll attempt the daily [leetcode](https://leetcode.com) prob
66

77
_**Note:** Our group is currently taking a break from grinding leetcode. The table below will continue to update automatically, but newer problems likey won't have their solutions provided. Pull requests will still be supported and reviewed if others would like to contribute solutions._
88

9+
## 🤖 Auto-Solver
10+
11+
We've added an automatic solver that uses OpenAI's GPT-5-mini to generate solutions for each day's problem! Every day at 00:01 UTC, the system automatically:
12+
- Fetches the daily LeetCode problem
13+
- Generates a thoughtful solution with explanations
14+
- Commits the solution as `gpt5-mini.md` in the problem's folder
15+
16+
This means you'll always find an AI-generated solution to compare with or learn from!
917

1018
# Problems we've attempted so far:
1119

auto_solver.py

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Auto-solver for daily LeetCode problems using OpenAI GPT-5-mini.
4+
This script fetches the daily problem, uses AI to solve it, and creates a solution file.
5+
"""
6+
7+
import os
8+
import sys
9+
import json
10+
import requests
11+
from datetime import datetime
12+
from openai import OpenAI
13+
14+
15+
def fetch_daily_problem():
16+
"""
17+
Fetch the daily LeetCode problem details using the GraphQL API.
18+
19+
Returns:
20+
dict: Problem details including ID, title, description, etc.
21+
"""
22+
leetcode_api_url = "https://leetcode.com/graphql"
23+
daily_challenge_query = {
24+
"query": """query questionOfToday {
25+
activeDailyCodingChallengeQuestion {
26+
date
27+
link
28+
question {
29+
questionFrontendId
30+
title
31+
titleSlug
32+
difficulty
33+
content
34+
exampleTestcases
35+
}
36+
}
37+
}""",
38+
"operationName": "questionOfToday"
39+
}
40+
41+
try:
42+
response = requests.post(leetcode_api_url, json=daily_challenge_query)
43+
response.raise_for_status()
44+
data = response.json()
45+
46+
if 'data' in data and 'activeDailyCodingChallengeQuestion' in data['data']:
47+
problem_data = data['data']['activeDailyCodingChallengeQuestion']
48+
question = problem_data['question']
49+
50+
return {
51+
'problem_id': question['questionFrontendId'],
52+
'title': question['title'],
53+
'title_slug': question['titleSlug'],
54+
'difficulty': question['difficulty'],
55+
'content': question['content'],
56+
'link': f"https://leetcode.com/problems/{question['titleSlug']}/description/?envType=daily-question",
57+
'example_testcases': question.get('exampleTestcases', '')
58+
}
59+
else:
60+
print("Error: Unexpected response structure from LeetCode API")
61+
print(json.dumps(data, indent=2))
62+
return None
63+
64+
except Exception as e:
65+
print(f"Error fetching daily problem: {e}")
66+
return None
67+
68+
69+
def generate_solution_with_ai(problem_info, api_key):
70+
"""
71+
Use OpenAI GPT-5-mini to generate a solution for the problem.
72+
73+
Args:
74+
problem_info (dict): Problem details from LeetCode
75+
api_key (str): OpenAI API key
76+
77+
Returns:
78+
str: Generated solution in markdown format
79+
"""
80+
try:
81+
client = OpenAI(api_key=api_key)
82+
83+
# Create a detailed prompt for the AI
84+
prompt = f"""You are solving a LeetCode problem. Generate a complete solution following this exact format:
85+
86+
# [Problem {problem_info['problem_id']}: {problem_info['title']}]({problem_info['link']})
87+
88+
## Initial thoughts (stream-of-consciousness)
89+
[Provide your initial thoughts about the problem, what approach comes to mind first, any observations about the problem structure]
90+
91+
## Refining the problem, round 2 thoughts
92+
[Discuss any refinements to your approach, edge cases to consider, alternative solutions, time/space complexity considerations]
93+
94+
## Attempted solution(s)
95+
```python
96+
[Provide a complete, working Python solution]
97+
```
98+
- [Add brief notes about the solution approach, complexity analysis, and any important implementation details]
99+
100+
Here is the problem:
101+
102+
**Title:** {problem_info['title']}
103+
**Difficulty:** {problem_info['difficulty']}
104+
**Link:** {problem_info['link']}
105+
106+
**Problem Description:**
107+
{problem_info['content']}
108+
109+
Please provide a thoughtful, well-explained solution that demonstrates clear problem-solving skills. The solution should be efficient and include proper complexity analysis."""
110+
111+
response = client.chat.completions.create(
112+
model="gpt-5-mini",
113+
messages=[
114+
{"role": "system", "content": "You are an expert software engineer solving LeetCode problems. Provide clear explanations and efficient solutions."},
115+
{"role": "user", "content": prompt}
116+
],
117+
temperature=0.7,
118+
max_tokens=2000
119+
)
120+
121+
return response.choices[0].message.content
122+
123+
except Exception as e:
124+
print(f"Error generating solution with AI: {e}")
125+
return None
126+
127+
128+
def save_solution(problem_id, solution_content):
129+
"""
130+
Save the generated solution to the appropriate file.
131+
132+
Args:
133+
problem_id (str): The LeetCode problem ID
134+
solution_content (str): The markdown content to save
135+
136+
Returns:
137+
str: Path to the created file
138+
"""
139+
try:
140+
problem_dir = f"problems/{problem_id}"
141+
os.makedirs(problem_dir, exist_ok=True)
142+
143+
solution_file = f"{problem_dir}/gpt5-mini.md"
144+
145+
with open(solution_file, 'w', encoding='utf-8') as f:
146+
f.write(solution_content)
147+
148+
print(f"Solution saved to: {solution_file}")
149+
return solution_file
150+
151+
except Exception as e:
152+
print(f"Error saving solution: {e}")
153+
return None
154+
155+
156+
def main():
157+
"""Main execution function."""
158+
print("=" * 60)
159+
print("LeetCode Auto-Solver - Starting...")
160+
print("=" * 60)
161+
162+
# Get OpenAI API key from environment
163+
api_key = os.environ.get('OPENAI_API_KEY')
164+
if not api_key:
165+
print("Error: OPENAI_API_KEY environment variable not set")
166+
sys.exit(1)
167+
168+
# Fetch today's problem
169+
print("\n1. Fetching daily LeetCode problem...")
170+
problem_info = fetch_daily_problem()
171+
if not problem_info:
172+
print("Failed to fetch daily problem")
173+
sys.exit(1)
174+
175+
print(f" Problem ID: {problem_info['problem_id']}")
176+
print(f" Title: {problem_info['title']}")
177+
print(f" Difficulty: {problem_info['difficulty']}")
178+
179+
# Generate solution using AI
180+
print("\n2. Generating solution with GPT-5-mini...")
181+
solution = generate_solution_with_ai(problem_info, api_key)
182+
if not solution:
183+
print("Failed to generate solution")
184+
sys.exit(1)
185+
186+
print(" Solution generated successfully!")
187+
188+
# Save the solution
189+
print("\n3. Saving solution to file...")
190+
saved_path = save_solution(problem_info['problem_id'], solution)
191+
if not saved_path:
192+
print("Failed to save solution")
193+
sys.exit(1)
194+
195+
print("\n" + "=" * 60)
196+
print("Auto-solver completed successfully!")
197+
print("=" * 60)
198+
199+
200+
if __name__ == "__main__":
201+
main()

0 commit comments

Comments
 (0)