Skip to content

Daily LeetCode Challenge #41

Daily LeetCode Challenge

Daily LeetCode Challenge #41

name: Daily LeetCode Challenge
on:
schedule:
- cron: '30 0 * * *' # 00:30 UTC, shortly after LeetCode daily reset
workflow_dispatch:
inputs:
problem_url:
description: 'LeetCode problem URL (leave empty for daily challenge)'
required: false
default: ''
jobs:
daily-leetcode:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Python dependencies
run: |
pip3 install html2text pyyaml
- name: Fetch LeetCode problem metadata
id: fetch
uses: ./.github/actions/fetch-leetcode-problem
with:
problem_url: ${{ inputs.problem_url }}
force_refetch: false
# ----------------------------------------------------------------
# Premium problem: create issue and stop
# ----------------------------------------------------------------
- name: Handle premium problem
if: steps.fetch.outputs.is_premium == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh issue create \
--title "Daily Challenge Skipped: Premium Problem - ${{ steps.fetch.outputs.title }}" \
--body "$(cat <<'EOF'
Problem #${{ steps.fetch.outputs.number }} — **${{ steps.fetch.outputs.title }}** is a premium problem and was skipped.
- **Date:** ${{ steps.fetch.outputs.date }}
- **Link:** https://leetcode.com/problems/${{ steps.fetch.outputs.slug }}/
EOF
)"
echo "::notice::Skipping premium problem – issue created."
# ----------------------------------------------------------------
# All remaining steps are skipped when the problem is premium
# ----------------------------------------------------------------
- name: Check for duplicate problem
if: steps.fetch.outputs.is_premium != 'true'
id: dup
run: |
if [ -d "problems/${{ steps.fetch.outputs.dir_name }}" ]; then
echo "is_duplicate=true" >> "$GITHUB_OUTPUT"
echo "::notice::Problem directory already exists – will use _daily_ suffix"
else
echo "is_duplicate=false" >> "$GITHUB_OUTPUT"
fi
- name: Build Claude prompt
if: steps.fetch.outputs.is_premium != 'true'
run: |
# Generate problem.json from problem.md for build-prompt.py
python3 scripts/parse-problem-md.py "problems/${{ steps.fetch.outputs.dir_name }}/problem.md" > problem.json
IS_DUPLICATE="${{ steps.dup.outputs.is_duplicate }}" \
DATE_COMPACT="${{ steps.fetch.outputs.date_compact }}" \
python3 scripts/build-prompt.py > prompt.txt
- name: Create working branch
if: steps.fetch.outputs.is_premium != 'true'
run: |
branch="feat/daily-${{ steps.fetch.outputs.date_compact }}-${{ steps.fetch.outputs.slug }}"
git checkout -b "$branch"
echo "BRANCH_NAME=$branch" >> "$GITHUB_ENV"
- name: Generate solution with Claude
if: steps.fetch.outputs.is_premium != 'true'
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
prompt: |
Read the file `prompt.txt` in the repository root. It contains a LeetCode problem
and detailed instructions for generating a DSA-coach analysis with progressive hints,
a Go solution, and Go table-driven tests.
Follow all formatting and naming instructions in the prompt. Write each file directly
to the filesystem using the Write tool:
- `problems/${{ steps.fetch.outputs.dir_name }}/analysis.md`
- `problems/${{ steps.fetch.outputs.dir_name }}/solution.go`
- `problems/${{ steps.fetch.outputs.dir_name }}/solution_test.go`
Do NOT use delimiters or print file contents to stdout. Create the actual files.
Do NOT run any git commands. Do NOT create commits or branches.
claude_args: |
--model opus
--max-turns 20
--allowedTools "Edit,MultiEdit,Write,Read,Glob,Grep,LS,Bash"
- name: Run tests
if: steps.fetch.outputs.is_premium != 'true'
id: test
continue-on-error: true
run: |
dir="problems/${{ steps.fetch.outputs.dir_name }}"
if [ ! -d "$dir" ]; then
echo "::error::Solution directory was not created by Claude"
echo "test_result=❌ No solution files generated" >> "$GITHUB_OUTPUT"
exit 1
fi
set +e
test_output=$(go test -v "./$dir/..." 2>&1)
test_exit=$?
set -e
echo "$test_output"
if [ $test_exit -eq 0 ]; then
echo "test_result=✅ All tests passed" >> "$GITHUB_OUTPUT"
else
passed=$(echo "$test_output" | grep -c "^--- PASS" || true)
failed=$(echo "$test_output" | grep -c "^--- FAIL" || true)
total=$((passed + failed))
if [ $total -gt 0 ]; then
echo "test_result=❌ ${failed} of ${total} tests failed" >> "$GITHUB_OUTPUT"
else
echo "test_result=❌ Tests failed to compile or run" >> "$GITHUB_OUTPUT"
fi
fi
- name: Check for existing PR
if: steps.fetch.outputs.is_premium != 'true'
id: existing_pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pr_url=$(gh pr list --head "$BRANCH_NAME" --state open --json url --jq '.[0].url // empty')
if [ -n "$pr_url" ]; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "::notice::PR already exists for this branch: $pr_url — skipping commit and PR creation."
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Commit and push solution
if: steps.fetch.outputs.is_premium != 'true' && steps.existing_pr.outputs.exists != 'true'
run: |
dir="problems/${{ steps.fetch.outputs.dir_name }}"
if [ ! -d "$dir" ] || [ -z "$(ls -A "$dir" 2>/dev/null)" ]; then
echo "::error::No solution files to commit"
exit 1
fi
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git"
git add "$dir"
git commit -m "feat: add solution for ${{ steps.fetch.outputs.number }}. ${{ steps.fetch.outputs.title }}"
git push -u origin "$BRANCH_NAME"
- name: Create pull request
if: steps.fetch.outputs.is_premium != 'true' && steps.existing_pr.outputs.exists != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pr_title="daily-${{ steps.fetch.outputs.date }}-${{ steps.fetch.outputs.number }}-${{ steps.fetch.outputs.slug }}"
gh pr create \
--head "$BRANCH_NAME" \
--title "$pr_title" \
--body "$(cat <<EOF
## Summary
- **Problem:** ${{ steps.fetch.outputs.number }}. ${{ steps.fetch.outputs.title }}
- **Difficulty:** ${{ steps.fetch.outputs.difficulty }}
- **Topics:** ${{ steps.fetch.outputs.topics }}
- **Link:** https://leetcode.com/problems/${{ steps.fetch.outputs.slug }}/
## Analysis Summary
See \`analysis.md\` in the PR files for progressive hints and detailed approach.
## Test Results
${{ steps.test.outputs.test_result }}
---
🤖 Generated with Claude (Anthropic API) using dsa-coach analysis
EOF
)"