@@ -42,15 +42,224 @@ Required fields for `leetcode_py/cli/resources/leetcode/json/problems/{problem_n
42
42
- ` playground_assertion ` : Use single quotes for string literals
43
43
- Double quotes in JSON + cookiecutter + Jupyter notebook = triple escaping issues
44
44
45
- ** Reference the complete template example:**
46
-
47
- See ` leetcode_py/cli/resources/leetcode/examples/example.json5 ` for a comprehensive template with:
48
-
49
- - All field definitions and variations
50
- - Comments explaining each field
51
- - Examples for different problem types (basic, tree, linked list, design, trie)
52
- - Proper JSON escaping rules for playground fields
53
- - Multiple solution class patterns
45
+ ** IMPORTANT: Create actual JSON files, not JSON5**
46
+
47
+ The template below uses JSON5 format with comments for documentation purposes only. When creating the actual ` .json ` file, you must:
48
+
49
+ 1 . ** Remove all comments** (lines starting with ` // ` )
50
+ 2 . ** Use proper JSON syntax** with quoted property names
51
+ 3 . ** Save as ` .json ` file** (not ` .json5 ` )
52
+
53
+ ** Template with comments (JSON5 format for reference only):**
54
+
55
+ ```` json5
56
+ {
57
+ // ============================================================================
58
+ // COMPREHENSIVE LEETCODE TEMPLATE EXAMPLE
59
+ // ============================================================================
60
+ // This example demonstrates ALL template patterns using valid_anagram as base
61
+ // with comprehensive comments showing variations for different problem types.
62
+ //
63
+ // REFERENCE PROBLEMS (see .templates/leetcode/json/ for complete examples):
64
+ // 1. valid_anagram - Basic: string parameters, boolean return
65
+ // 2. invert_binary_tree - Tree: TreeNode imports/parameters
66
+ // 3. merge_two_sorted_lists - LinkedList: ListNode imports/parameters
67
+ // 4. lru_cache - Design: custom class, multiple methods, operations
68
+ // 5. implement_trie_prefix_tree - Trie: DictTree inheritance
69
+ // ============================================================================
70
+
71
+ // === PROBLEM IDENTIFICATION ===
72
+ problem_name: " valid_anagram" , // snake_case: used for directory/file names
73
+ solution_class_name: " Solution" , // "Solution" for basic problems
74
+ // "LRUCache" for design problems
75
+ // "Trie(DictTree[str])" for inheritance
76
+ problem_number: " 242" , // LeetCode problem number as string
77
+ problem_title: " Valid Anagram" , // Exact title from LeetCode
78
+ difficulty: " Easy" , // Easy, Medium, Hard
79
+ topics: " Hash Table, String, Sorting" , // Comma-separated topics from LeetCode
80
+ _tags: { list: [" grind-75" ] }, // Optional: common problem set tags
81
+ // Use _tags wrapper for cookiecutter lists
82
+
83
+ // === README CONTENT ===
84
+ // IMPORTANT: Preserve rich HTML content from LeetCode including:
85
+ // - Code snippets with backticks: `code`
86
+ // - Bold text: **bold** or <strong>bold</strong>
87
+ // - Italic text: *italic* or <em>italic</em>
88
+ // - Images: 
89
+ // - HTML formatting: <p>, <br>, <ul>, <li>, etc.
90
+ // - Mathematical expressions and special characters
91
+ readme_description: " Given two strings `s` and `t`, return `true` if `t` is an anagram of `s`, and `false` otherwise." ,
92
+
93
+ _readme_examples: {
94
+ // Use _readme_examples wrapper for cookiecutter lists
95
+ list: [
96
+ { content: ' ```\n Input: s = "anagram", t = "nagaram"\n Output: true\n ```' },
97
+ { content: ' ```\n Input: s = "rat", t = "car"\n Output: false\n ```' },
98
+ // For tree problems: Include images
99
+ // { "content": "\n\n```\nInput: root = [4,2,7,1,3,6,9]\nOutput: [4,7,2,9,6,3,1]\n```" }
100
+ ],
101
+ },
102
+
103
+ readme_constraints: " - 1 <= s.length, t.length <= 5 * 10^4\n - s and t consist of lowercase English letters." ,
104
+ readme_additional: " **Follow up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case?" ,
105
+
106
+ // === HELPER FUNCTIONS ===
107
+ // New template system uses helper functions for cleaner test organization
108
+ helpers_imports: " " , // Empty for basic problems
109
+ // "from leetcode_py import TreeNode" for tree problems
110
+ // "from leetcode_py import ListNode" for linked list problems
111
+ helpers_content: " " , // Additional helper content if needed
112
+ helpers_run_name: " is_anagram" , // Function name matching main method
113
+ helpers_run_signature: " (solution_class: type, s: str, t: str)" ,
114
+ // For tree: "(solution_class: type, root_list: list[int | None])"
115
+ // For linked list: "(solution_class: type, list1_vals: list[int], list2_vals: list[int])"
116
+ // For design: "(solution_class: type, operations: list[str], inputs: list[list[int]])"
117
+ helpers_run_body: " implementation = solution_class()\n return implementation.is_anagram(s, t)" ,
118
+ // For tree: " root = TreeNode[int].from_list(root_list)\n implementation = solution_class()\n return implementation.invert_tree(root)"
119
+ // For design: " cache = None\n results: list[int | None] = []\n # ... operation loop ...\n return results, cache"
120
+ helpers_assert_name: " is_anagram" , // Function name matching main method
121
+ helpers_assert_signature: " (result: bool, expected: bool) -> bool" ,
122
+ // For tree: "(result: TreeNode[int] | None, expected_list: list[int | None]) -> bool"
123
+ // For design: "(result: list[int | None], expected: list[int | None]) -> bool"
124
+ helpers_assert_body: " assert result == expected\n return True" ,
125
+ // For tree: " expected = TreeNode[int].from_list(expected_list)\n assert result == expected\n return True"
126
+
127
+ // === SOLUTION TEMPLATE ===
128
+ solution_imports: " " , // Empty for basic problems
129
+ // "from leetcode_py import TreeNode" for tree problems
130
+ // "from leetcode_py import ListNode" for linked list problems
131
+ // "from leetcode_py.data_structures import DictTree, RecursiveDict" for trie problems
132
+ solution_contents: " " , // Additional content before class definition
133
+ solution_class_content: " " , // Content inside class definition (usually empty)
134
+
135
+ // === TEST CONFIGURATION ===
136
+ test_imports: " import pytest\n from leetcode_py import logged_test\n from .helpers import assert_is_anagram, run_is_anagram\n from .solution import Solution" ,
137
+ // For design: "from .solution import LRUCache" instead of Solution
138
+ test_content: " " , // Additional test content
139
+ test_class_name: " ValidAnagram" , // PascalCase: TestClassName for pytest class
140
+ test_class_content: " def setup_method(self):\n self.solution = Solution()" ,
141
+ // Empty for design problems: ""
142
+
143
+ // === SOLUTION METHODS ===
144
+ _solution_methods: {
145
+ // Use _solution_methods wrapper for cookiecutter lists
146
+ list: [
147
+ {
148
+ name: " is_anagram" , // snake_case method name
149
+ signature: " (self, s: str, t: str) -> bool" , // Full method signature with type hints
150
+ // For tree: "(self, root: TreeNode[int] | None) -> TreeNode[int] | None"
151
+ // For linked list: "(self, list1: ListNode[int] | None, list2: ListNode[int] | None) -> ListNode[int] | None"
152
+ body: " # TODO: Implement is_anagram\n return False" ,
153
+ // For design problems with __init__:
154
+ // { "name": "__init__", "signature": "(self, capacity: int) -> None", "body": " # TODO: Initialize\n pass" }
155
+ },
156
+ ],
157
+ },
158
+
159
+ // === TEST HELPER METHODS ===
160
+ _test_helper_methods: {
161
+ // Use _test_helper_methods wrapper for cookiecutter lists
162
+ list: [
163
+ { name: " setup_method" , parameters: " " , body: " self.solution = Solution()" },
164
+ // Empty list for design problems: []
165
+ ],
166
+ },
167
+
168
+ // === TEST METHODS ===
169
+ _test_methods: {
170
+ // Use _test_methods wrapper for cookiecutter lists
171
+ list: [
172
+ {
173
+ name: " test_is_anagram" , // test_{method_name}
174
+ signature: " (self, s: str, t: str, expected: bool)" , // Method signature with type hints
175
+ parametrize: " s, t, expected" , // pytest parametrize parameters
176
+ // For tree: "root_list, expected_list"
177
+ // For design: "operations, inputs, expected"
178
+ test_cases: " [('anagram', 'nagaram', True), ('rat', 'car', False), ('listen', 'silent', True), ('hello', 'bello', False), ('', '', True), ('a', 'a', True), ('a', 'b', False), ('ab', 'ba', True), ('abc', 'bca', True), ('abc', 'def', False), ('aab', 'abb', False), ('aabbcc', 'abcabc', True), ('abcd', 'abcde', False), ('race', 'care', True), ('elbow', 'below', True), ('study', 'dusty', True), ('night', 'thing', True), ('stressed', 'desserts', True)]" ,
179
+ // For tree: "[([4, 2, 7, 1, 3, 6, 9], [4, 7, 2, 9, 6, 3, 1]), ([2, 1, 3], [2, 3, 1]), ([], [])]"
180
+ // For design: "[(['LRUCache', 'put', 'get'], [[2], [1, 1], [1]], [None, None, 1])]"
181
+ body: " result = run_is_anagram(Solution, s, t)\n assert_is_anagram(result, expected)" ,
182
+ // For tree: " result = run_invert_tree(Solution, root_list)\n assert_invert_tree(result, expected_list)"
183
+ // For design: " result, _ = run_lru_cache(LRUCache, operations, inputs)\n assert_lru_cache(result, expected)"
184
+ },
185
+ ],
186
+ },
187
+
188
+ // === PLAYGROUND NOTEBOOK ===
189
+ // CRITICAL: Use single quotes for Python strings to avoid JSON escaping issues with Jupyter notebooks
190
+ // Double quotes in JSON + cookiecutter + Jupyter notebook = triple escaping issues
191
+ // ALWAYS use single quotes: s = 'hello', not s = "hello"
192
+ playground_imports: " from helpers import run_is_anagram, assert_is_anagram\n from solution import Solution" ,
193
+ // For tree: "from helpers import run_invert_tree, assert_invert_tree\nfrom solution import Solution\nfrom leetcode_py import TreeNode"
194
+ // For design: "from helpers import run_lru_cache, assert_lru_cache\nfrom solution import LRUCache"
195
+ playground_setup: " # Example test case\n s = 'anagram'\n t = 'nagaram'\n expected = True" ,
196
+ // For tree: "# Example test case\nroot_list: list[int | None] = [4, 2, 7, 1, 3, 6, 9]\nexpected_list: list[int | None] = [4, 7, 2, 9, 6, 3, 1]"
197
+ // For design: "# Example test case\noperations = ['LRUCache', 'put', 'get']\ninputs = [[2], [1, 1], [1]]\nexpected = [None, None, 1]"
198
+ playground_run: " result = run_is_anagram(Solution, s, t)\n result" ,
199
+ // For tree: "result = run_invert_tree(Solution, root_list)\nresult"
200
+ // For design: "result, cache = run_lru_cache(LRUCache, operations, inputs)\nprint(result)\ncache"
201
+ playground_assert: " assert_is_anagram(result, expected)" ,
202
+ // For tree: "assert_invert_tree(result, expected_list)"
203
+ // For design: "assert_lru_cache(result, expected)"
204
+
205
+ // ============================================================================
206
+ // PROBLEM TYPE VARIATIONS SUMMARY:
207
+ // ============================================================================
208
+ //
209
+ // BASIC PROBLEMS (valid_anagram):
210
+ // - solution_class_name: "Solution"
211
+ // - solution_imports: ""
212
+ // - Simple method signatures: "(self, s: str, t: str) -> bool"
213
+ // - Basic test cases: string/number parameters
214
+ // - Playground: single quotes for strings
215
+ //
216
+ // TREE PROBLEMS (invert_binary_tree):
217
+ // - solution_class_name: "Solution"
218
+ // - solution_imports: "from leetcode_py import TreeNode"
219
+ // - Tree method signatures: "(self, root: TreeNode[int] | None) -> TreeNode[int] | None"
220
+ // - Helper functions use TreeNode.from_list()
221
+ // - Test cases: list representations of trees
222
+ // - Playground: TreeNode imports and list conversions
223
+ //
224
+ // LINKED LIST PROBLEMS (merge_two_sorted_lists):
225
+ // - solution_class_name: "Solution"
226
+ // - solution_imports: "from leetcode_py import ListNode"
227
+ // - List method signatures: "(self, list1: ListNode[int] | None, list2: ListNode[int] | None) -> ListNode[int] | None"
228
+ // - Helper functions use ListNode.from_list()
229
+ // - Test cases: list representations of linked lists
230
+ // - Playground: ListNode imports and list conversions
231
+ //
232
+ // DESIGN PROBLEMS (lru_cache):
233
+ // - solution_class_name: "LRUCache" (custom class name)
234
+ // - Multiple methods including __init__
235
+ // - Operations-based testing: operations, inputs, expected arrays
236
+ // - Complex test body with operation loops
237
+ // - Helper functions return (results, instance) for debugging
238
+ // - Playground: print results, return instance
239
+ // - test_class_content: "" (no setup_method)
240
+ //
241
+ // INHERITANCE PROBLEMS (implement_trie_prefix_tree):
242
+ // - solution_class_name: "Trie(DictTree[str])" (with inheritance)
243
+ // - solution_imports: "from leetcode_py.data_structures import DictTree, RecursiveDict"
244
+ // - Custom class with inheritance from DictTree
245
+ // - Operations-based testing like design problems
246
+ // - Helper functions return (results, instance) for debugging
247
+ //
248
+ // MULTIPLE SOLUTIONS (invert_binary_tree, lru_cache):
249
+ // - Add parametrize for solution classes in test files:
250
+ // @pytest.mark.parametrize("solution_class", [Solution, SolutionDFS, SolutionBFS])
251
+ // @pytest.mark.parametrize("solution_class", [LRUCache, LRUCacheWithDoublyList])
252
+ // - Update test method signature to include solution_class parameter
253
+ // - Import all solution classes in test file
254
+ // ============================================================================
255
+ }
256
+ ````
257
+
258
+ ** IMPORTANT: When creating the actual .json file, convert the above JSON5 to valid JSON by:**
259
+
260
+ 1 . ** Remove all comments** (lines starting with ` // ` )
261
+ 2 . ** Keep all quoted property names** (already done above)
262
+ 3 . ** Save as ` .json ` file** (not ` .json5 ` )
54
263
55
264
## Naming Conventions
56
265
0 commit comments