Skip to content

Commit 4bef09d

Browse files
committed
feat: add 5 more leetcodes
1 parent 36be7a9 commit 4bef09d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1846
-30
lines changed

.cursor/.dev/next_problem.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# Import the problem lists
77
sys.path.append(str(Path(__file__).parent.parent.parent))
88
from problem_lists import available_lists
9+
from problem_lists.unscrapable import get_unscrapable_numbers
910
from problem_lists.utils import get_existing_problems
1011

1112

@@ -15,6 +16,7 @@ def get_next_problem(tag_names=None):
1516
tag_names = list(available_lists.keys())
1617

1718
existing_problems = get_existing_problems()
19+
unscrapable_numbers = get_unscrapable_numbers()
1820

1921
# Find the list with the lowest missing problems
2022
best_list = None
@@ -24,7 +26,8 @@ def get_next_problem(tag_names=None):
2426
for tag_name, problem_tuples in available_lists.items():
2527
if tag_name in tag_names:
2628
problem_numbers = {num for num, _ in problem_tuples}
27-
missing = problem_numbers - existing_problems
29+
# Exclude unscrapable problems from missing problems
30+
missing = problem_numbers - existing_problems - unscrapable_numbers
2831
missing_count = len(missing)
2932

3033
if missing_count > 0 and missing_count < min_missing:
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Unscrapable Problems List
2+
# Problems that cannot be scraped due to being premium, having API issues, or other technical limitations
3+
4+
# Format: (problem_number, problem_name)
5+
UNSCRAPABLE_PROBLEMS = [
6+
(252, "meeting-rooms"),
7+
(253, "meeting-rooms-ii"),
8+
(261, "graph-valid-tree"),
9+
(271, "encode-and-decode-strings"),
10+
(323, "number-of-connected-components-in-an-undirected-graph"),
11+
# Add more unscrapable problems as discovered
12+
]
13+
14+
15+
# Helper function to check if a problem is unscrapable
16+
def is_unscrapable(problem_number: int) -> bool:
17+
"""Check if a problem number is in the unscrapable list."""
18+
return any(num == problem_number for num, _ in UNSCRAPABLE_PROBLEMS)
19+
20+
21+
def is_unscrapable_by_name(problem_name: str) -> bool:
22+
"""Check if a problem name is in the unscrapable list."""
23+
return any(name == problem_name for _, name in UNSCRAPABLE_PROBLEMS)
24+
25+
26+
def get_unscrapable_numbers() -> set[int]:
27+
"""Get all unscrapable problem numbers as a set."""
28+
return {num for num, _ in UNSCRAPABLE_PROBLEMS}

.cursor/.dev/update_tags.json

Lines changed: 0 additions & 17 deletions
This file was deleted.

.cursor/commands/batch-problem-creation.md

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ When user requests **batch creation of multiple problems**, the assistant will:
99
3. **For each problem**:
1010
- Find next problem via `poetry run python .cursor/.dev/next_problem.py`
1111
- Follow all steps from `.cursor/commands/problem-creation.md`
12-
- Verify reproducibility and quality via `.cursor/commands/test-quality-assurance.md`
12+
- **MANDATORY**: Read and follow `.cursor/commands/test-quality-assurance.md` for quality verification
1313
4. **Provide batch summary** at the end
1414

15+
**CRITICAL INSTRUCTION**: You MUST read the test-quality-assurance.md file before executing quality assurance for any problem. Do not rely on memory or assumptions about the workflow.
16+
1517
## High-Level Process
1618

1719
### Step 1: Initialize Batch
@@ -32,6 +34,7 @@ poetry run python .cursor/.dev/next_problem.py
3234

3335
- Extract problem number and name from output
3436
- Log progress: "Problem X/Count: #NUMBER - NAME"
37+
- **Note**: The script automatically excludes unscrapable problems (premium, API issues, etc.)
3538

3639
#### 2.2: Follow Problem Creation Workflow
3740

@@ -55,15 +58,17 @@ Execute complete workflow from `.cursor/commands/problem-creation.md`:
5558
3. **Use parametrized testing**: Ensure all solution approaches are tested
5659
4. **Verify correctness**: Solution must handle all test cases correctly
5760

58-
#### 2.4: Quality Assurance
61+
#### 2.4: Quality Assurance & Reproducibility Verification
62+
63+
**MANDATORY**: You MUST read and follow the complete workflow from `.cursor/commands/test-quality-assurance.md` for EVERY problem.
64+
65+
**REQUIRED ACTION**: Before proceeding with quality assurance, you MUST:
5966

60-
Execute workflow from `.cursor/commands/test-quality-assurance.md`:
67+
1. **Read the file**: `read_file /Users/wisl/Desktop/vault/personal-repo/leetcode-py/.cursor/commands/test-quality-assurance.md`
68+
2. **Follow the exact 4-step process** described in that file
69+
3. **Execute each step** as specified in the test-quality-assurance.md workflow
6170

62-
1. **Run tests**: `make p-test PROBLEM={problem_name}`
63-
2. **Check test coverage**: Ensure minimum 12 test cases
64-
3. **Enhance if needed**: Update JSON with more test cases
65-
4. **Verify reproducibility**: Ensure all tests pass consistently
66-
5. **Final verification**: `make p-lint PROBLEM={problem_name}`
71+
**CRITICAL**: Do NOT proceed without reading the test-quality-assurance.md file first. The workflow includes specific backup, regenerate, and restore steps that must be followed exactly.
6772

6873
### Step 3: Batch Summary
6974

@@ -142,11 +147,12 @@ Next Steps: All problems created successfully!
142147

143148
### Common failure scenarios:
144149

145-
- Scraping fails (problem not found)
150+
- Scraping fails (problem not found, premium problem, API issues)
146151
- JSON template issues (invalid syntax)
147152
- Generation fails (missing dependencies)
148153
- Tests fail (incorrect expected values)
149154
- Linting errors (template problems)
155+
- Unscrapable problems (automatically excluded by next_problem.py)
150156

151157
### Recovery actions:
152158

@@ -155,6 +161,9 @@ Next Steps: All problems created successfully!
155161
- **Generation**: Check Makefile and dependencies
156162
- **Tests**: Update expected values in JSON template
157163
- **Linting**: Fix template issues and regenerate
164+
- **Unscrapable**: Add to `.cursor/.dev/problem_lists/unscrapable.py` and continue with next problem
165+
166+
**CRITICAL**: Never edit generated files directly (helpers.py, test_solution.py, README.md, etc.). Always fix issues in the JSON template and regenerate to ensure reproducibility. The ONLY exception is solution.py implementation - you may edit this file directly to implement the optimal solution.
158167

159168
## Success Criteria
160169

@@ -166,10 +175,13 @@ Each problem must meet:
166175
-**Parametrized testing** for all solution approaches
167176
- ✅ Linting passes without errors
168177
- ✅ All tests pass
169-
- ✅ Minimum 12 comprehensive test cases
178+
-**test-quality-assurance.md file read and complete workflow executed**
179+
- ✅ Minimum 12 comprehensive test cases (verified via check_test_cases tool)
180+
-**Test reproducibility verified** (tests pass consistently)
170181
- ✅ Images included in README if available
171-
- ✅ Proper JSON template created
182+
- ✅ Proper JSON template created and updated
172183
- ✅ Code coverage includes edge cases
184+
-**Original solution preserved** after quality assurance process
173185

174186
## Batch Parameters
175187

@@ -178,6 +190,26 @@ Each problem must meet:
178190
- **Force**: Whether to overwrite existing problems
179191
- **Dry Run**: Preview mode without actual creation
180192

193+
## Unscrapable Problems Management
194+
195+
### Adding Unscrapable Problems
196+
197+
When encountering a problem that cannot be scraped (premium, API issues, etc.):
198+
199+
1. **Add to unscrapable list**: Update `.cursor/.dev/problem_lists/unscrapable.py`
200+
2. **Format**: `(problem_number, "problem-name")`
201+
3. **Continue batch**: The next_problem.py script will automatically skip unscrapable problems
202+
203+
### Example unscrapable.py entry:
204+
205+
```python
206+
UNSCRAPABLE_PROBLEMS = [
207+
(252, "meeting-rooms"),
208+
(253, "meeting-rooms-ii"), # if also unscrapable
209+
# Add more as discovered
210+
]
211+
```
212+
181213
## Notes
182214

183215
- **Sequential Processing**: Create one problem at a time to avoid conflicts
@@ -187,3 +219,4 @@ Each problem must meet:
187219
- **Quality Focus**: Ensure each problem meets all quality standards
188220
- **Reproducibility**: Verify tests pass consistently with implemented solutions
189221
- **Documentation**: Maintain clear logs of the entire process
222+
- **Unscrapable Handling**: Automatically exclude known unscrapable problems

.cursor/commands/update-tags.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Update Tags Command
2+
3+
## Description
4+
5+
Updates `.tags.json5` by running the `update_tags.py` script, sorting the output alphabetically, and cleaning up temporary files. The LLM handles this process directly to preserve comments in the JSON5 file.
6+
7+
## Usage
8+
9+
When user requests "update tags" or "update-tags", the assistant will:
10+
11+
1. **Run update script**: Execute `poetry run python .cursor/.dev/update_tags.py`
12+
2. **Read output**: Read the generated `.cursor/.dev/update_tags.json` file
13+
3. **Read current tags**: Read the existing `.tags.json5` file to preserve comments
14+
4. **Sort and merge**: Sort the new tags alphabetically by name and merge with existing structure
15+
5. **Update file**: Write the updated tags to `.tags.json5` while preserving comments
16+
6. **Cleanup**: Delete the temporary `.cursor/.dev/update_tags.json` file
17+
18+
## LLM Workflow
19+
20+
```python
21+
# 1. Run the update script
22+
poetry run python .cursor/.dev/update_tags.py
23+
24+
# 2. Read the generated JSON file
25+
with open('.cursor/.dev/update_tags.json', 'r') as f:
26+
new_tags = json.load(f)
27+
28+
# 3. Read existing .tags.json5 to preserve comments
29+
with open('.tags.json5', 'r') as f:
30+
existing_content = f.read()
31+
32+
# 4. Sort new tags alphabetically by name
33+
sorted_tags = sorted(new_tags, key=lambda x: x.get('name', ''))
34+
35+
# 5. Update the .tags.json5 file while preserving comments
36+
# (Implementation depends on JSON5 structure and comment preservation needs)
37+
38+
# 6. Clean up temporary file
39+
os.remove('.cursor/.dev/update_tags.json')
40+
```
41+
42+
## Prerequisites
43+
44+
- `update_tags.py` script must exist in `.cursor/.dev/`
45+
- The script must output a JSON file to `.cursor/.dev/update_tags.json`
46+
- Assistant must handle JSON5 comment preservation
47+
48+
## Output
49+
50+
- Updates `.tags.json5` with alphabetically sorted tags
51+
- Preserves existing comments in the JSON5 file
52+
- Removes temporary `.cursor/.dev/update_tags.json` file
53+
- Provides success/error feedback

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PYTHON_VERSION = 3.13
2-
PROBLEM ?= number_of_1_bits
2+
PROBLEM ?= top_k_frequent_elements
33
FORCE ?= 0
44
COMMA := ,
55

leetcode/counting_bits/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Counting Bits
2+
3+
**Difficulty:** Easy
4+
**Topics:** Dynamic Programming, Bit Manipulation
5+
**Tags:** blind-75
6+
7+
**LeetCode:** [Problem 338](https://leetcode.com/problems/counting-bits/description/)
8+
9+
## Problem Description
10+
11+
Given an integer `n`, return _an array_ `ans` _of length_ `n + 1` _such that for each_ `i` _(0 <= i <= n),_ `ans[i]` \*is the **number of\*** `1`**\*'s** in the binary representation of\* `i`.
12+
13+
## Examples
14+
15+
### Example 1:
16+
17+
```
18+
Input: n = 2
19+
Output: [0,1,1]
20+
Explanation:
21+
0 --> 0
22+
1 --> 1
23+
2 --> 10
24+
```
25+
26+
### Example 2:
27+
28+
```
29+
Input: n = 5
30+
Output: [0,1,1,2,1,2]
31+
Explanation:
32+
0 --> 0
33+
1 --> 1
34+
2 --> 10
35+
3 --> 11
36+
4 --> 100
37+
5 --> 101
38+
```
39+
40+
## Constraints
41+
42+
- 0 <= n <= 10^5
43+
44+
**Follow up:**
45+
46+
- It is very easy to come up with a solution with a runtime of `O(n log n)`. Can you do it in linear time `O(n)` and possibly in a single pass?
47+
- Can you do it without using any built-in function (i.e., like `__builtin_popcount` in C++)?

leetcode/counting_bits/__init__.py

Whitespace-only changes.

leetcode/counting_bits/helpers.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
def run_count_bits(solution_class: type, n: int):
2+
implementation = solution_class()
3+
return implementation.count_bits(n)
4+
5+
6+
def assert_count_bits(result: list[int], expected: list[int]) -> bool:
7+
assert result == expected
8+
return True
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# ---
2+
# jupyter:
3+
# jupytext:
4+
# text_representation:
5+
# extension: .py
6+
# format_name: percent
7+
# format_version: '1.3'
8+
# jupytext_version: 1.17.3
9+
# kernelspec:
10+
# display_name: leetcode-py-py3.13
11+
# language: python
12+
# name: python3
13+
# ---
14+
15+
# %%
16+
from helpers import assert_count_bits, run_count_bits
17+
from solution import Solution
18+
19+
# %%
20+
# Example test case
21+
n = 2
22+
expected = [0, 1, 1]
23+
24+
# %%
25+
result = run_count_bits(Solution, n)
26+
result
27+
28+
# %%
29+
assert_count_bits(result, expected)

0 commit comments

Comments
 (0)