Skip to content

Commit 66644cd

Browse files
authored
feat: add lru problem (#14)
1 parent 489a971 commit 66644cd

Some content is hidden

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

45 files changed

+1542
-364
lines changed
File renamed without changes.
File renamed without changes.

.amazonq/rules/problem-creation.md

Lines changed: 97 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,108 @@
11
# Problem Creation Guide
22

3-
## Quick Steps
3+
## Assistant Workflow
44

5-
1. Create JSON: `.templates/leetcode/json/{problem_name}.json`
6-
2. Update Makefile: `PROBLEM ?= your_new_problem`
7-
3. Generate: `make p-gen`
8-
4. Verify: `make lint`
9-
5. **If you edit generated files**: Update JSON template, then `make p-gen FORCE=1` to ensure reproducibility
5+
When user requests a problem by **number** or **name/slug**, the assistant will:
106

11-
## JSON Template Rules
7+
1. **Scrape** problem data using `.templates/leetcode/scrape.py`
8+
2. **Transform** data into proper JSON template format
9+
3. **Create** JSON file in `.templates/leetcode/json/{problem_name}.json`
10+
4. **Update** Makefile with `PROBLEM ?= {problem_name}`
11+
5. **Generate** problem structure using `make p-gen`
12+
6. **Verify** with `make lint` - fix template issues in JSON if possible, or manually fix generated files if template limitations
13+
7. **Iterate** if JSON fixes: re-run `make p-gen PROBLEM={problem_name} FORCE=1` and `make lint` until passes to ensure reproducibility
1214

13-
- **Copy from reference examples** - don't create from scratch
14-
- **Tree problems**: Use `.templates/leetcode/examples/tree.json5`
15-
- **Basic problems**: Use `.templates/leetcode/examples/basic.json5`
16-
- **Don't add extra fields** - templates are complete
17-
- **Python naming convention**: Use snake_case for all parameter names (e.g., `new_interval` not `newInterval`)
18-
- **If lint fails**: Fix JSON and regenerate, don't edit generated files
19-
- **After any manual edits**: Always update JSON template and verify with `make p-gen FORCE=1`
15+
## Scraping Commands
2016

21-
## Tags (Optional)
17+
```bash
18+
# Fetch by number
19+
poetry run python .templates/leetcode/scrape.py -n 1
20+
21+
# Fetch by slug
22+
poetry run python .templates/leetcode/scrape.py -s "two-sum"
23+
```
24+
25+
## JSON Template Format
26+
27+
Required fields for `.templates/leetcode/json/{problem_name}.json`:
28+
29+
**Reference examples in `.templates/leetcode/examples/` for complete templates:**
30+
31+
- `basic.json5` - Array, string, number problems
32+
- `tree.json5` - Binary tree problems
33+
- `linked_list.json5` - Linked list problems
34+
- `string.json5` - String manipulation problems
35+
- `matrix.json5` - 2D array/matrix problems
2236

2337
```json
24-
"tags": ["grind-75", "blind-75", "neetcode-150", "top-interview"]
38+
{
39+
"problem_name": "two_sum",
40+
"class_name": "TwoSum",
41+
"method_name": "two_sum",
42+
"problem_number": "1",
43+
"problem_title": "Two Sum",
44+
"difficulty": "Easy",
45+
"topics": "Array, Hash Table",
46+
"tags": ["grind-75"],
47+
"problem_description": "Given an array...",
48+
"examples": [{ "input": "nums = [2,7,11,15], target = 9", "output": "[0,1]" }],
49+
"constraints": "- 2 <= nums.length <= 10^4",
50+
"parameters": "nums: list[int], target: int",
51+
"return_type": "list[int]",
52+
"dummy_return": "[]",
53+
"imports": "",
54+
"test_cases": [{ "args": [[2, 7, 11, 15], 9], "expected": [0, 1] }],
55+
"param_names": "nums, target, expected",
56+
"param_names_with_types": "nums: list[int], target: int, expected: list[int]",
57+
"input_description": "nums={nums}, target={target}",
58+
"input_params": "nums, target",
59+
"expected_param": "expected",
60+
"method_args": "nums, target",
61+
"test_setup": "",
62+
"test_logging": "",
63+
"assertion_code": "assert result == expected",
64+
"test_input_setup": "nums = [2, 7, 11, 15]\ntarget = 9",
65+
"expected_output_setup": "expected = [0, 1]"
66+
}
2567
```
2668

27-
## Helper Classes
69+
## Naming Conventions
70+
71+
- **problem_name**: snake_case (e.g., "two_sum", "valid_palindrome")
72+
- **class_name**: PascalCase (e.g., "TwoSum", "ValidPalindrome")
73+
- **method_name**: snake_case (e.g., "two_sum", "is_palindrome")
74+
- **parameters**: Use snake_case for all parameter names
75+
76+
## Special Problem Types
77+
78+
### Tree Problems
79+
80+
- Add `"imports": "from leetcode_py.tree_node import TreeNode"`
81+
- Use `TreeNode | None` for nullable tree parameters
82+
- Test setup: `root = TreeNode.from_list(root_list)`
83+
84+
### Linked List Problems
85+
86+
- Add `"imports": "from leetcode_py.list_node import ListNode"`
87+
- Use `ListNode | None` for nullable list parameters
88+
- Test setup: `head = ListNode.from_list(head_list)`
89+
90+
## Generation Commands
91+
92+
```bash
93+
# Generate problem
94+
make p-gen PROBLEM={problem_name}
95+
96+
# Force regenerate (if files exist)
97+
make p-gen PROBLEM={problem_name} FORCE=1
98+
99+
# Test specific problem
100+
make p-test PROBLEM={problem_name}
101+
102+
# Lint check
103+
make lint
104+
```
105+
106+
## Tags (Optional)
28107

29-
- TreeNode: `from leetcode_py.tree_node import TreeNode`
30-
- ListNode: `from leetcode_py.list_node import ListNode`
31-
- New helpers: Add to `leetcode_py/`
108+
Common tags: `["grind-75", "blind-75", "neetcode-150", "top-interview"]`

.templates/leetcode/examples/basic.json5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"method_name": "two_sum",
99

1010
// REQUIRED: Problem metadata
11-
"problem_number": "1",
11+
"problem_number": "1", // OPTIONAL: omit if no LeetCode number
1212
"problem_title": "Two Sum",
1313
"difficulty": "Easy",
1414
"topics": "Array, Hash Table",
Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,62 @@
11
{
2-
// Linked list problem template
3-
// Use this for problems involving ListNode structures
4-
5-
// REQUIRED: Core identifiers
6-
"problem_name": "reverse_linked_list_ii",
7-
"class_name": "ReverseLinkedListII",
8-
"method_name": "reverse_between",
9-
10-
// REQUIRED: Problem metadata
11-
"problem_number": "92",
12-
"problem_title": "Reverse Linked List II",
13-
"difficulty": "Medium",
14-
"topics": "Linked List",
15-
16-
// OPTIONAL: Problem categorization
17-
"tags": [],
18-
19-
// REQUIRED: Problem description
20-
"problem_description": "Given the head of a singly linked list and two integers left and right where left <= right, reverse the nodes of the list from position left to position right, and return the reversed list.",
21-
22-
// REQUIRED: Examples
23-
"examples": [
24-
{ "input": "head = [1,2,3,4,5], left = 2, right = 4", "output": "[1,4,3,2,5]" },
25-
{ "input": "head = [5], left = 1, right = 1", "output": "[5]" }
26-
],
27-
28-
// REQUIRED: Constraints
29-
"constraints": "- The number of nodes in the list is n.\n- 1 <= n <= 500\n- -500 <= Node.val <= 500\n- 1 <= left <= right <= n",
30-
31-
// REQUIRED: Method signature
32-
"parameters": "head: ListNode | None, left: int, right: int",
33-
"return_type": "ListNode | None",
34-
"dummy_return": "None",
35-
36-
// REQUIRED: ListNode import for linked list problems
37-
"imports": "from leetcode_py.list_node import ListNode",
38-
39-
// REQUIRED: Test cases
40-
"test_cases": [
41-
{ "args": [[1, 2, 3, 4, 5], 2, 4], "expected": [1, 4, 3, 2, 5] },
42-
{ "args": [[5], 1, 1], "expected": [5] },
43-
{ "args": [[1, 2, 3], 1, 3], "expected": [3, 2, 1] }
44-
],
45-
46-
// REQUIRED: Test parameters (use expected_list for linked list problems)
47-
"param_names": "head_list, left, right, expected_list",
48-
"param_names_with_types": "head_list: list[int], left: int, right: int, expected_list: list[int]",
49-
"input_description": "head_list={head_list}, left={left}, right={right}",
50-
"input_params": "head, left, right",
51-
"expected_param": "expected",
52-
"method_args": "head, left, right",
53-
54-
// REQUIRED: Linked list-specific test setup
55-
"test_setup": "head = ListNode.from_list(head_list)\nexpected = ListNode.from_list(expected_list)",
56-
"test_logging": "logger.success(f\"Got result: {result.to_list() if result else []}\")",
57-
"assertion_code": "assert result == expected",
58-
59-
// REQUIRED: Notebook setup for linked list problems
60-
"test_input_setup": "# Example test case\nhead = ListNode.from_list([1, 2, 3, 4, 5])\nleft = 2\nright = 4",
61-
"expected_output_setup": "expected = ListNode.from_list([1, 4, 3, 2, 5])"
2+
// Linked list problem template
3+
// Use this for problems involving ListNode structures
4+
5+
// REQUIRED: Core identifiers
6+
problem_name: "reverse_linked_list_ii",
7+
class_name: "ReverseLinkedListII",
8+
method_name: "reverse_between",
9+
10+
// REQUIRED: Problem metadata
11+
problem_number: "92", // OPTIONAL: omit if no LeetCode number
12+
problem_title: "Reverse Linked List II",
13+
difficulty: "Medium",
14+
topics: "Linked List",
15+
16+
// OPTIONAL: Problem categorization
17+
tags: [],
18+
19+
// REQUIRED: Problem description
20+
problem_description: "Given the head of a singly linked list and two integers left and right where left <= right, reverse the nodes of the list from position left to position right, and return the reversed list.",
21+
22+
// REQUIRED: Examples
23+
examples: [
24+
{ input: "head = [1,2,3,4,5], left = 2, right = 4", output: "[1,4,3,2,5]" },
25+
{ input: "head = [5], left = 1, right = 1", output: "[5]" },
26+
],
27+
28+
// REQUIRED: Constraints
29+
constraints: "- The number of nodes in the list is n.\n- 1 <= n <= 500\n- -500 <= Node.val <= 500\n- 1 <= left <= right <= n",
30+
31+
// REQUIRED: Method signature
32+
parameters: "head: ListNode | None, left: int, right: int",
33+
return_type: "ListNode | None",
34+
dummy_return: "None",
35+
36+
// REQUIRED: ListNode import for linked list problems
37+
imports: "from leetcode_py import ListNode",
38+
39+
// REQUIRED: Test cases
40+
test_cases: [
41+
{ args: [[1, 2, 3, 4, 5], 2, 4], expected: [1, 4, 3, 2, 5] },
42+
{ args: [[5], 1, 1], expected: [5] },
43+
{ args: [[1, 2, 3], 1, 3], expected: [3, 2, 1] },
44+
],
45+
46+
// REQUIRED: Test parameters (use expected_list for linked list problems)
47+
param_names: "head_list, left, right, expected_list",
48+
param_names_with_types: "head_list: list[int], left: int, right: int, expected_list: list[int]",
49+
input_description: "head_list={head_list}, left={left}, right={right}",
50+
input_params: "head, left, right",
51+
expected_param: "expected",
52+
method_args: "head, left, right",
53+
54+
// REQUIRED: Linked list-specific test setup
55+
test_setup: "head = ListNode.from_list(head_list)\nexpected = ListNode.from_list(expected_list)",
56+
test_logging: 'logger.success(f"Got result: {result.to_list() if result else []}")',
57+
assertion_code: "assert result == expected",
58+
59+
// REQUIRED: Notebook setup for linked list problems
60+
test_input_setup: "# Example test case\nhead = ListNode.from_list([1, 2, 3, 4, 5])\nleft = 2\nright = 4",
61+
expected_output_setup: "expected = ListNode.from_list([1, 4, 3, 2, 5])",
6262
}

.templates/leetcode/examples/matrix.json5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"method_name": "rotate",
99

1010
// REQUIRED: Problem metadata
11-
"problem_number": "48",
11+
"problem_number": "48", // OPTIONAL: omit if no LeetCode number
1212
"problem_title": "Rotate Image",
1313
"difficulty": "Medium",
1414
"topics": "Array, Math, Matrix",

.templates/leetcode/examples/string.json5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"method_name": "is_palindrome",
99

1010
// REQUIRED: Problem metadata
11-
"problem_number": "125",
11+
"problem_number": "125", // OPTIONAL: omit if no LeetCode number
1212
"problem_title": "Valid Palindrome",
1313
"difficulty": "Easy",
1414
"topics": "Two Pointers, String",

0 commit comments

Comments
 (0)