|
| 1 | +{ |
| 2 | + // ============================================================================ |
| 3 | + // COMPREHENSIVE LEETCODE TEMPLATE EXAMPLE |
| 4 | + // ============================================================================ |
| 5 | + // This example demonstrates ALL template patterns using valid_anagram as base |
| 6 | + // with comprehensive comments showing variations for different problem types. |
| 7 | + // |
| 8 | + // REFERENCE PROBLEMS (see .templates/leetcode/json/ for complete examples): |
| 9 | + // 1. valid_anagram - Basic: string parameters, boolean return |
| 10 | + // 2. invert_binary_tree - Tree: TreeNode imports/parameters |
| 11 | + // 3. merge_two_sorted_lists - LinkedList: ListNode imports/parameters |
| 12 | + // 4. lru_cache - Design: custom class, multiple methods, operations |
| 13 | + // 5. implement_trie_prefix_tree - Trie: DictTree inheritance |
| 14 | + // ============================================================================ |
| 15 | + |
| 16 | + // === PROBLEM IDENTIFICATION === |
| 17 | + "problem_name": "valid_anagram", // snake_case: used for directory/file names |
| 18 | + "solution_class_name": "Solution", // "Solution" for basic problems |
| 19 | + // "LRUCache" for design problems |
| 20 | + // "Trie(DictTree[str])" for inheritance |
| 21 | + "problem_number": "242", // LeetCode problem number as string |
| 22 | + "problem_title": "Valid Anagram", // Exact title from LeetCode |
| 23 | + "difficulty": "Easy", // Easy, Medium, Hard |
| 24 | + "topics": "Hash Table, String, Sorting", // Comma-separated topics from LeetCode |
| 25 | + "_tags": { "list": ["grind-75"] }, // Optional: common problem set tags |
| 26 | + // Use _tags wrapper for cookiecutter lists |
| 27 | + |
| 28 | + // === README CONTENT === |
| 29 | + // IMPORTANT: Preserve rich HTML content from LeetCode including: |
| 30 | + // - Code snippets with backticks: `code` |
| 31 | + // - Bold text: **bold** or <strong>bold</strong> |
| 32 | + // - Italic text: *italic* or <em>italic</em> |
| 33 | + // - Images:  |
| 34 | + // - HTML formatting: <p>, <br>, <ul>, <li>, etc. |
| 35 | + // - Mathematical expressions and special characters |
| 36 | + "readme_description": "Given two strings `s` and `t`, return `true` if `t` is an anagram of `s`, and `false` otherwise.", |
| 37 | + |
| 38 | + "_readme_examples": { // Use _readme_examples wrapper for cookiecutter lists |
| 39 | + "list": [ |
| 40 | + { "content": "```\nInput: s = \"anagram\", t = \"nagaram\"\nOutput: true\n```" }, |
| 41 | + { "content": "```\nInput: s = \"rat\", t = \"car\"\nOutput: false\n```" } |
| 42 | + // For tree problems: Include images |
| 43 | + // { "content": "\n\n```\nInput: root = [4,2,7,1,3,6,9]\nOutput: [4,7,2,9,6,3,1]\n```" } |
| 44 | + ] |
| 45 | + }, |
| 46 | + |
| 47 | + "readme_constraints": "- 1 <= s.length, t.length <= 5 * 10^4\n- s and t consist of lowercase English letters.", |
| 48 | + "readme_additional": "**Follow up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case?", |
| 49 | + |
| 50 | + // === HELPER FUNCTIONS === |
| 51 | + // New template system uses helper functions for cleaner test organization |
| 52 | + "helpers_imports": "", // Empty for basic problems |
| 53 | + // "from leetcode_py import TreeNode" for tree problems |
| 54 | + // "from leetcode_py import ListNode" for linked list problems |
| 55 | + "helpers_content": "", // Additional helper content if needed |
| 56 | + "helpers_run_name": "is_anagram", // Function name matching main method |
| 57 | + "helpers_run_signature": "(solution_class: type, s: str, t: str)", |
| 58 | + // For tree: "(solution_class: type, root_list: list[int | None])" |
| 59 | + // For linked list: "(solution_class: type, list1_vals: list[int], list2_vals: list[int])" |
| 60 | + // For design: "(solution_class: type, operations: list[str], inputs: list[list[int]])" |
| 61 | + "helpers_run_body": " implementation = solution_class()\n return implementation.is_anagram(s, t)", |
| 62 | + // For tree: " root = TreeNode[int].from_list(root_list)\n implementation = solution_class()\n return implementation.invert_tree(root)" |
| 63 | + // For design: " cache = None\n results: list[int | None] = []\n # ... operation loop ...\n return results, cache" |
| 64 | + "helpers_assert_name": "is_anagram", // Function name matching main method |
| 65 | + "helpers_assert_signature": "(result: bool, expected: bool) -> bool", |
| 66 | + // For tree: "(result: TreeNode[int] | None, expected_list: list[int | None]) -> bool" |
| 67 | + // For design: "(result: list[int | None], expected: list[int | None]) -> bool" |
| 68 | + "helpers_assert_body": " assert result == expected\n return True", |
| 69 | + // For tree: " expected = TreeNode[int].from_list(expected_list)\n assert result == expected\n return True" |
| 70 | + |
| 71 | + // === SOLUTION TEMPLATE === |
| 72 | + "solution_imports": "", // Empty for basic problems |
| 73 | + // "from leetcode_py import TreeNode" for tree problems |
| 74 | + // "from leetcode_py import ListNode" for linked list problems |
| 75 | + // "from leetcode_py.data_structures import DictTree, RecursiveDict" for trie problems |
| 76 | + "solution_contents": "", // Additional content before class definition |
| 77 | + "solution_class_content": "", // Content inside class definition (usually empty) |
| 78 | + |
| 79 | + // === TEST CONFIGURATION === |
| 80 | + "test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .helpers import assert_is_anagram, run_is_anagram\nfrom .solution import Solution", |
| 81 | + // For design: "from .solution import LRUCache" instead of Solution |
| 82 | + "test_content": "", // Additional test content |
| 83 | + "test_class_name": "ValidAnagram", // PascalCase: TestClassName for pytest class |
| 84 | + "test_class_content": " def setup_method(self):\n self.solution = Solution()", |
| 85 | + // Empty for design problems: "" |
| 86 | + |
| 87 | + // === SOLUTION METHODS === |
| 88 | + "_solution_methods": { // Use _solution_methods wrapper for cookiecutter lists |
| 89 | + "list": [ |
| 90 | + { |
| 91 | + "name": "is_anagram", // snake_case method name |
| 92 | + "signature": "(self, s: str, t: str) -> bool", // Full method signature with type hints |
| 93 | + // For tree: "(self, root: TreeNode[int] | None) -> TreeNode[int] | None" |
| 94 | + // For linked list: "(self, list1: ListNode[int] | None, list2: ListNode[int] | None) -> ListNode[int] | None" |
| 95 | + "body": " # TODO: Implement is_anagram\n return False" |
| 96 | + // For design problems with __init__: |
| 97 | + // { "name": "__init__", "signature": "(self, capacity: int) -> None", "body": " # TODO: Initialize\n pass" } |
| 98 | + } |
| 99 | + ] |
| 100 | + }, |
| 101 | + |
| 102 | + // === TEST HELPER METHODS === |
| 103 | + "_test_helper_methods": { // Use _test_helper_methods wrapper for cookiecutter lists |
| 104 | + "list": [ |
| 105 | + { "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" } |
| 106 | + // Empty list for design problems: [] |
| 107 | + ] |
| 108 | + }, |
| 109 | + |
| 110 | + // === TEST METHODS === |
| 111 | + "_test_methods": { // Use _test_methods wrapper for cookiecutter lists |
| 112 | + "list": [ |
| 113 | + { |
| 114 | + "name": "test_is_anagram", // test_{method_name} |
| 115 | + "signature": "(self, s: str, t: str, expected: bool)", // Method signature with type hints |
| 116 | + "parametrize": "s, t, expected", // pytest parametrize parameters |
| 117 | + // For tree: "root_list, expected_list" |
| 118 | + // For design: "operations, inputs, expected" |
| 119 | + "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)]", |
| 120 | + // For tree: "[([4, 2, 7, 1, 3, 6, 9], [4, 7, 2, 9, 6, 3, 1]), ([2, 1, 3], [2, 3, 1]), ([], [])]" |
| 121 | + // For design: "[(['LRUCache', 'put', 'get'], [[2], [1, 1], [1]], [None, None, 1])]" |
| 122 | + "body": " result = run_is_anagram(Solution, s, t)\n assert_is_anagram(result, expected)" |
| 123 | + // For tree: " result = run_invert_tree(Solution, root_list)\n assert_invert_tree(result, expected_list)" |
| 124 | + // For design: " result, _ = run_lru_cache(LRUCache, operations, inputs)\n assert_lru_cache(result, expected)" |
| 125 | + } |
| 126 | + ] |
| 127 | + }, |
| 128 | + |
| 129 | + // === PLAYGROUND NOTEBOOK === |
| 130 | + // CRITICAL: Use single quotes for Python strings to avoid JSON escaping issues with Jupyter notebooks |
| 131 | + // Double quotes in JSON + cookiecutter + Jupyter notebook = triple escaping issues |
| 132 | + // ALWAYS use single quotes: s = 'hello', not s = "hello" |
| 133 | + "playground_imports": "from helpers import run_is_anagram, assert_is_anagram\nfrom solution import Solution", |
| 134 | + // For tree: "from helpers import run_invert_tree, assert_invert_tree\nfrom solution import Solution\nfrom leetcode_py import TreeNode" |
| 135 | + // For design: "from helpers import run_lru_cache, assert_lru_cache\nfrom solution import LRUCache" |
| 136 | + "playground_setup": "# Example test case\ns = 'anagram'\nt = 'nagaram'\nexpected = True", |
| 137 | + // 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]" |
| 138 | + // For design: "# Example test case\noperations = ['LRUCache', 'put', 'get']\ninputs = [[2], [1, 1], [1]]\nexpected = [None, None, 1]" |
| 139 | + "playground_run": "result = run_is_anagram(Solution, s, t)\nresult", |
| 140 | + // For tree: "result = run_invert_tree(Solution, root_list)\nresult" |
| 141 | + // For design: "result, cache = run_lru_cache(LRUCache, operations, inputs)\nprint(result)\ncache" |
| 142 | + "playground_assert": "assert_is_anagram(result, expected)" |
| 143 | + // For tree: "assert_invert_tree(result, expected_list)" |
| 144 | + // For design: "assert_lru_cache(result, expected)" |
| 145 | + |
| 146 | + // ============================================================================ |
| 147 | + // PROBLEM TYPE VARIATIONS SUMMARY: |
| 148 | + // ============================================================================ |
| 149 | + // |
| 150 | + // BASIC PROBLEMS (valid_anagram): |
| 151 | + // - solution_class_name: "Solution" |
| 152 | + // - solution_imports: "" |
| 153 | + // - Simple method signatures: "(self, s: str, t: str) -> bool" |
| 154 | + // - Basic test cases: string/number parameters |
| 155 | + // - Playground: single quotes for strings |
| 156 | + // |
| 157 | + // TREE PROBLEMS (invert_binary_tree): |
| 158 | + // - solution_class_name: "Solution" |
| 159 | + // - solution_imports: "from leetcode_py import TreeNode" |
| 160 | + // - Tree method signatures: "(self, root: TreeNode[int] | None) -> TreeNode[int] | None" |
| 161 | + // - Helper functions use TreeNode.from_list() |
| 162 | + // - Test cases: list representations of trees |
| 163 | + // - Playground: TreeNode imports and list conversions |
| 164 | + // |
| 165 | + // LINKED LIST PROBLEMS (merge_two_sorted_lists): |
| 166 | + // - solution_class_name: "Solution" |
| 167 | + // - solution_imports: "from leetcode_py import ListNode" |
| 168 | + // - List method signatures: "(self, list1: ListNode[int] | None, list2: ListNode[int] | None) -> ListNode[int] | None" |
| 169 | + // - Helper functions use ListNode.from_list() |
| 170 | + // - Test cases: list representations of linked lists |
| 171 | + // - Playground: ListNode imports and list conversions |
| 172 | + // |
| 173 | + // DESIGN PROBLEMS (lru_cache): |
| 174 | + // - solution_class_name: "LRUCache" (custom class name) |
| 175 | + // - Multiple methods including __init__ |
| 176 | + // - Operations-based testing: operations, inputs, expected arrays |
| 177 | + // - Complex test body with operation loops |
| 178 | + // - Helper functions return (results, instance) for debugging |
| 179 | + // - Playground: print results, return instance |
| 180 | + // - test_class_content: "" (no setup_method) |
| 181 | + // |
| 182 | + // INHERITANCE PROBLEMS (implement_trie_prefix_tree): |
| 183 | + // - solution_class_name: "Trie(DictTree[str])" (with inheritance) |
| 184 | + // - solution_imports: "from leetcode_py.data_structures import DictTree, RecursiveDict" |
| 185 | + // - Custom class with inheritance from DictTree |
| 186 | + // - Operations-based testing like design problems |
| 187 | + // - Helper functions return (results, instance) for debugging |
| 188 | + // |
| 189 | + // MULTIPLE SOLUTIONS (invert_binary_tree, lru_cache): |
| 190 | + // - Add parametrize for solution classes in test files: |
| 191 | + // @pytest.mark.parametrize("solution_class", [Solution, SolutionDFS, SolutionBFS]) |
| 192 | + // @pytest.mark.parametrize("solution_class", [LRUCache, LRUCacheWithDoublyList]) |
| 193 | + // - Update test method signature to include solution_class parameter |
| 194 | + // - Import all solution classes in test file |
| 195 | + // ============================================================================ |
| 196 | +} |
0 commit comments