Skip to content

Commit 14d3221

Browse files
Add auto-solver using GPT-5-mini for daily LeetCode problems
Co-authored-by: jeremymanning <9030494+jeremymanning@users.noreply.github.com>
1 parent 452d5dd commit 14d3221

File tree

2 files changed

+239
-0
lines changed

2 files changed

+239
-0
lines changed

.github/workflows/auto_solver.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v3
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v4
19+
with:
20+
python-version: '3.11'
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install requests openai
26+
27+
- name: Run auto-solver
28+
env:
29+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
30+
run: |
31+
python auto_solver.py
32+
33+
- name: Commit and push changes
34+
uses: stefanzweifel/git-auto-commit-action@v4
35+
with:
36+
commit_message: "Auto-solve daily LeetCode problem using GPT-5-mini"
37+
branch: main
38+
file_pattern: problems/*/gpt5-mini.md

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)