diff --git a/.amazonq/plans/.gitkeep b/.amazonq/plans/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/.amazonq/plans/02-cookiecutter-template-improvement.md b/.amazonq/plans/02-cookiecutter-template-improvement.md
deleted file mode 100644
index acc78a5..0000000
--- a/.amazonq/plans/02-cookiecutter-template-improvement.md
+++ /dev/null
@@ -1,266 +0,0 @@
-# Plan: Improve Cookiecutter Template for LeetCode Problems
-
-## Overview
-
-Improve the cookiecutter template to be more general and cover all LeetCode question types, including special cases like LRU Cache that use custom class names and multiple methods.
-
-## Current Issues Identified
-
-1. **Hard-coded class name**: Template assumes `Solution` class but some problems use custom classes (e.g., `LRUCache`)
-2. **Single method assumption**: Template assumes one method but some problems have multiple methods (`__init__`, `get`, `put`)
-3. **Complex test setup**: Current template doesn't handle operation-based testing for design problems
-4. **Import handling**: Need better solution import structure
-5. **Template parameter explosion**: Too many derived parameters that could be simplified
-
-## Target Structure
-
-```
-.templates/leetcode/
-├── {{cookiecutter.problem_name}}/
-│ ├── __init__.py
-│ ├── solution.py
-│ ├── tests.py
-│ ├── README.md
-│ └── playground.ipynb
-└── cookiecutter.json
-```
-
-## Phase 1: Analyze Problem Types
-
-### 1.1 Universal Template Variables
-
-- `solution_imports`: Required imports for solution.py (empty, TreeNode, ListNode, etc.)
-- `test_imports`: All import lines for tests.py (pytest, loguru, TreeNode, test_utils, solution class)
-- `solution_class_name`: Dynamic class name (Solution, LRUCache, etc.)
-- `readme_description`: Problem description for README (supports HTML including images, preserves code snippets like `x`, `y`, `some_params`)
-- `readme_examples`: Examples for README (supports HTML including images, typically uses code blocks for input/output)
-- `readme_constraints`: Constraints for README
-- `readme_additional`: Additional README sections
-- `solution_methods`: List of methods with parameters/return types
-- `test_methods`: List of test methods with parametrize and body
-- `test_helper_methods`: List of test helper methods (setup_method, teardown_method, utility methods, etc.)
-
-## Phase 2: Create New cookiecutter.json
-
-### 2.1 Complete Template Variables Example
-
-````json
-{
- "problem_name": "two_sum",
- "solution_class_name": "Solution",
- "problem_number": "1",
- "problem_title": "Two Sum",
- "difficulty": "Easy",
- "topics": "Array, Hash Table",
- "tags": ["grind-75"],
-
- "readme_description": "Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`.\n\n\n\nYou may assume that each input would have exactly one solution, and you may not use the same element twice.",
- "readme_examples": [
- {
- "content": "```\nInput: nums = [2,7,11,15], target = 9\nOutput: [0,1]\n```\n**Explanation:** Because nums[0] + nums[1] == 9, we return [0, 1]."
- },
- {
- "content": "
\n\n```\nInput: root = [4,2,7,1,3,6,9]\nOutput: [4,7,2,9,6,3,1]\n```\n**Explanation:** The tree is inverted as shown in the image above."
- }
- ],
- "readme_constraints": "- 2 <= nums.length <= 10^4\n- -10^9 <= nums[i] <= 10^9\n- -10^9 <= target <= 10^9\n- Only one valid answer exists.",
- "readme_additional": "",
-
- "solution_imports": "",
- "solution_methods": [
- {
- "name": "two_sum",
- "parameters": "nums: list[int], target: int",
- "return_type": "list[int]",
- "dummy_return": "[]"
- }
- ],
-
- "test_imports": "import pytest\nfrom loguru import logger\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
- "test_helper_methods": [
- {
- "name": "setup_method",
- "parameters": "",
- "body": "self.solution = Solution()"
- }
- ],
- "test_methods": [
- {
- "name": "test_two_sum",
- "parametrize": "nums, target, expected",
- "test_cases": "[([2, 7, 11, 15], 9, [0, 1]), ([3, 2, 4], 6, [1, 2])]",
- "body": "result = self.solution.two_sum(nums, target)\nassert result == expected"
- }
- ],
-
- "playground_imports": "from solution import Solution",
- "playground_test_case": "# Example test case\nnums = [2, 7, 11, 15]\ntarget = 9\nexpected = [0, 1]",
- "playground_execution": "result = Solution().two_sum(nums, target)\nresult",
- "playground_assertion": "assert result == expected"
-}
-````
-
-## Phase 3: Update Template Files
-
-### 3.1 solution.py Template
-
-```python
-{{cookiecutter.solution_imports}}
-
-class {{cookiecutter.solution_class_name}}:
- {% for method in cookiecutter.solution_methods %}
- # Time: O(?)
- # Space: O(?)
- def {{method.name}}(self, {{method.parameters}}) -> {{method.return_type}}:
- # TODO: Implement {{method.name}}
- return {{method.dummy_return}}
-
- {% endfor %}
-```
-
-### 3.2 tests.py Template
-
-```python
-{{cookiecutter.test_imports}}
-
-class Test{{cookiecutter.solution_class_name}}:
- {% for method in cookiecutter.test_helper_methods %}
- def {{method.name}}(self{% if method.parameters %}, {{method.parameters}}{% endif %}):
- {{method.body}}
-
- {% endfor %}
-
- {% for method in cookiecutter.test_methods %}
- @pytest.mark.parametrize("{{method.parametrize}}", {{method.test_cases}})
- @logged_test
- def {{method.name}}(self, {{method.parametrize}}):
- {{method.body}}
-
- {% endfor %}
-```
-
-### 3.3 README.md Template
-
-```markdown
-# {{cookiecutter.problem_title}}
-
-**Difficulty:** {{cookiecutter.difficulty}}
-**Topics:** {{cookiecutter.topics}}
-**Tags:** {{cookiecutter.tags | join(', ')}}
-{% if cookiecutter.problem_number %}
-**LeetCode:** [Problem {{cookiecutter.problem_number}}](https://leetcode.com/problems/{{cookiecutter.problem_name.replace('_', "-")}}/description/)
-{% endif %}
-
-## Problem Description
-
-{{cookiecutter.readme_description}}
-
-## Examples
-
-{% for example in cookiecutter.readme_examples %}
-
-### Example {{loop.index}}:
-
-{{example.content}}
-{% endfor %}
-
-## Constraints
-
-{{cookiecutter.readme_constraints}}
-
-{% if cookiecutter.readme_additional %}
-{{cookiecutter.readme_additional}}
-{% endif %}
-```
-
-### 3.4 playground.ipynb Template
-
-```json
-{
- "cells": [
- {
- "cell_type": "code",
- "id": "imports",
- "source": ["{{cookiecutter.playground_imports}}"]
- },
- {
- "cell_type": "code",
- "id": "setup",
- "source": ["{{cookiecutter.playground_test_case}}"]
- },
- {
- "cell_type": "code",
- "id": "execute",
- "source": ["{{cookiecutter.playground_execution}}"]
- },
- {
- "cell_type": "code",
- "id": "test",
- "source": ["{{cookiecutter.playground_assertion}}"]
- }
- ]
-}
-```
-
-## Phase 4: Simplify Parameter Generation
-
-### 4.1 Reduce Template Complexity
-
-- Remove derived parameters like `param_names`, `input_description`, etc.
-- Generate these dynamically in the template using Jinja2 filters
-- Focus on core data: methods, test_cases, problem metadata
-
-### 4.2 Smart Defaults
-
-- Auto-generate method names from problem names
-- Auto-generate class names from problem names
-- Default to "basic" problem type unless specified
-
-## Phase 5: Testing & Validation
-
-### 5.1 Test with Existing Problems
-
-- Generate all current problems using new template
-- Compare output with existing generated files
-- Ensure no regression in functionality
-
-### 5.2 Test Special Cases
-
-- LRU Cache (design problem)
-- Tree problems (TreeNode imports)
-- Linked list problems (ListNode imports)
-- Matrix problems (2D arrays)
-
-## Phase 6: Integration
-
-### 6.1 Update Generation Scripts
-
-- Modify `gen.py` to work with new template structure
-- Update Makefile commands
-- Ensure backward compatibility with existing JSON files
-
-### 6.2 Documentation
-
-- Update problem creation guide
-- Create examples for each problem type
-- Document new template variables
-
-## Success Criteria
-
-1. ✅ Single cookiecutter template handles all problem types
-2. ✅ Reduced template complexity (fewer derived parameters)
-3. ✅ Support for design problems with multiple methods
-4. ✅ Proper imports for tree/linked list problems
-5. ✅ Clean, maintainable template structure
-6. ✅ All existing problems can be regenerated without issues
-7. ✅ New problem types can be easily added
-
-## Implementation Order
-
-1. Create new `cookiecutter.json` structure
-2. Update template files with conditional logic
-3. Test with basic problems (Two Sum)
-4. Test with design problems (LRU Cache)
-5. Test with tree/linked list problems
-6. Validate all existing problems
-7. Update generation scripts and documentation
diff --git a/.amazonq/plans/03-regenerate-all-problems.md b/.amazonq/plans/03-regenerate-all-problems.md
deleted file mode 100644
index e993f26..0000000
--- a/.amazonq/plans/03-regenerate-all-problems.md
+++ /dev/null
@@ -1,228 +0,0 @@
-# Plan: Regenerate All Problems with Fresh LeetCode Data
-
-## Overview
-
-Scrape fresh data from LeetCode for existing problems and generate new JSON files using the new universal cookiecutter template, ensuring all generated code passes linting.
-
-## Current State Analysis
-
-- Old JSON files: `.templates/leetcode/old/template/json/*.json` (for problem names only)
-- Scraper: `.templates/leetcode/scrape.py` (existing)
-- New template: `.templates/leetcode/cookiecutter.json` + templates
-- Target: `.templates/leetcode/json/*.json` (new format with fresh data)
-- Generated problems: `leetcode/*/`
-
-## Phase 1: Extract Problem Names
-
-### 1.1 Get Problem Names from Old JSON
-
-```bash
-ls .templates/leetcode/old/template/json/
-```
-
-Expected problems:
-
-- container_with_most_water.json
-- insert_interval.json
-- invert_binary_tree.json
-- lru_cache.json
-- reverse_linked_list_ii.json
-- spiral_matrix.json
-
-### 1.2 Extract Problem Numbers/Slugs
-
-From old JSON files, extract:
-
-- Problem numbers (for scraping by number)
-- Problem names/slugs (for scraping by slug)
-
-## Phase 2: Create Fresh Scraping Script
-
-### 2.1 Use Existing Scraper
-
-Following the problem creation rules:
-
-```bash
-# Fetch by number
-poetry run python .templates/leetcode/scrape.py -n 1
-
-# Fetch by slug
-poetry run python .templates/leetcode/scrape.py -s "two-sum"
-```
-
-### 2.2 Scraping Script: `scrape_all_problems.py`
-
-✅ **Created** - Uses existing scraper to fetch fresh data for all problems
-
-## Phase 3: Execute Fresh Scraping
-
-### 3.1 Run Scraping Script
-
-```bash
-cd .templates/leetcode
-python scrape_all_problems.py
-```
-
-### 3.2 Transform JSON to New Template Format
-
-The scraper creates JSON in new template format automatically.
-
-### 3.3 Verify New JSON Files
-
-```bash
-ls .templates/leetcode/json/
-# Should show all freshly scraped JSON files
-```
-
-## Phase 4: Test Generation Pipeline
-
-### 4.1 Test Single Problem Generation
-
-```bash
-make p-gen PROBLEM=container_with_most_water FORCE=1
-```
-
-### 4.2 Verify Generated Structure
-
-```bash
-ls leetcode/container_with_most_water/
-# Should show: __init__.py, solution.py, tests.py, README.md, playground.ipynb
-```
-
-### 4.3 Test Linting on Single Problem
-
-```bash
-make lint
-# Should pass without errors
-```
-
-## Phase 5: Full Regeneration
-
-### 5.1 Update Makefile (if needed)
-
-Verify `gen-all-problems` target works with new template:
-
-```makefile
-gen-all-problems:
- @echo "This will DELETE all existing problems and regenerate from JSON templates."
- @read -p "Are you sure? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1
- @echo "Deleting existing problems..."
- @rm -rf leetcode/*/
- @echo "Generating all problems..."
- @for json_file in .templates/leetcode/json/*.json; do \
- problem=$$(basename "$$json_file" .json); \
- echo "Generating: $$problem"; \
- poetry run python .templates/leetcode/gen.py "$$json_file" --force; \
- done
-```
-
-### 5.2 Run Full Regeneration
-
-```bash
-make gen-all-problems FORCE=1
-```
-
-### 5.3 Verify All Problems Generated
-
-```bash
-ls leetcode/
-# Should show all problem directories
-```
-
-## Phase 6: Validation & Iteration
-
-### 6.1 Run Linting on All Problems
-
-```bash
-make lint
-```
-
-### 6.2 Fix Issues (Iterative Process)
-
-**If linting fails:**
-
-1. **Identify Issue Type:**
- - Template formatting issues → Fix template files
- - JSON data issues → Re-scrape or manually fix JSON
- - Import issues → Fix template imports
-
-2. **Fix and Regenerate:**
-
- ```bash
- # Fix issue in template or JSON
- make gen-all-problems FORCE=1
- make lint
- ```
-
-3. **Repeat until clean:**
- - Continue iteration until `make lint` passes
- - Ensure reproducible generation
-
-### 6.3 Common Issues & Fixes
-
-**Template Issues:**
-
-- Indentation problems → Fix Jinja2 `indent` filters in templates
-- Missing imports → Update template import generation
-- Method signatures → Fix solution_methods in JSON
-
-**JSON Issues:**
-
-- Missing required fields → Re-scrape with updated scraper
-- Incorrect data types → Fix scraper output format
-- Test case format → Update scraper test case generation
-
-## Phase 7: Validation Testing
-
-### 7.1 Test Individual Problems
-
-```bash
-make p-test PROBLEM=container_with_most_water
-make p-test PROBLEM=lru_cache
-make p-test PROBLEM=invert_binary_tree
-```
-
-### 7.2 Run Full Test Suite
-
-```bash
-make test
-```
-
-### 7.3 Verify Notebooks Work
-
-- Check playground.ipynb files can be opened
-- Verify cell content is properly formatted
-
-## Success Criteria
-
-1. ✅ All old JSON files migrated to new format
-2. ✅ `make gen-all-problems` works with new template
-3. ✅ All generated problems pass `make lint`
-4. ✅ All generated problems pass `make test`
-5. ✅ Generation is reproducible (no manual fixes needed)
-6. ✅ All problem types work (basic, design, tree, linked list)
-
-## Implementation Order
-
-1. **Create scraping script** - Get fresh data from LeetCode
-2. **Run fresh scraping** - Generate new JSON files
-3. **Test single problem** - Verify pipeline works
-4. **Fix template issues** - Ensure clean generation
-5. **Run full regeneration** - Generate all problems
-6. **Iterate on linting** - Fix issues until clean
-7. **Final validation** - Test all problems work
-
-## Rollback Plan
-
-If issues arise:
-
-1. Keep old template in `.templates/leetcode/old/`
-2. Can revert to old generation method
-3. New template is additive, doesn't break existing workflow
-
-## Notes
-
-- Focus on reproducible generation without manual intervention
-- Prioritize linting compliance over perfect formatting
-- Document any template limitations discovered during migration
-- Ensure backward compatibility with existing JSON structure
diff --git a/.amazonq/plans/compare_template_files.py b/.amazonq/plans/compare_template_files.py
deleted file mode 100644
index aeb083a..0000000
--- a/.amazonq/plans/compare_template_files.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python3
-"""Reusable file comparison tool for template validation."""
-
-import difflib
-from pathlib import Path
-
-import typer
-
-
-def compare_files(file1: Path, file2: Path, label1: str, label2: str) -> bool:
- """Compare two files and show differences. Returns True if identical."""
- typer.echo(f"\n{'='*60}")
- typer.echo(f"COMPARING: {file1.name}")
- typer.echo(f"{label1}: {file1}")
- typer.echo(f"{label2}: {file2}")
- typer.echo(f"{'='*60}")
-
- if not file1.exists():
- typer.echo(f"❌ MISSING: {file1} does not exist")
- return False
-
- if not file2.exists():
- typer.echo(f"❌ MISSING: {file2} does not exist")
- return False
-
- content1 = file1.read_text().splitlines(keepends=True)
- content2 = file2.read_text().splitlines(keepends=True)
-
- diff = list(
- difflib.unified_diff(
- content1,
- content2,
- fromfile=f"{label1}/{file1.name}",
- tofile=f"{label2}/{file2.name}",
- lineterm="",
- )
- )
-
- if not diff:
- typer.echo("✅ FILES IDENTICAL")
- return True
- else:
- typer.echo("❌ DIFFERENCES FOUND:")
- for line in diff:
- typer.echo(line)
- return False
-
-
-def main(
- mode: str = typer.Argument(help="Compare template files or generated files (template|generated)"),
- problem: str = typer.Option("invert_binary_tree", help="Problem name for comparison"),
-):
- """Compare files for template validation."""
- if mode not in ["template", "generated"]:
- typer.echo(f"❌ ERROR: Invalid mode '{mode}'. Use 'template' or 'generated'")
- return
-
- base_dir = Path(__file__).parent.parent.parent
-
- files_to_compare = ["solution.py", "tests.py", "README.md", "playground.ipynb", "__init__.py"]
-
- if mode == "template":
- # Compare reference vs template source
- dir1 = base_dir / "leetcode" / ".example" / problem
- dir2 = base_dir / ".templates" / "leetcode" / ".example" / "{{cookiecutter.problem_name}}"
- label1, label2 = "Reference", "Template"
- typer.echo("TEMPLATE SOURCE ANALYSIS")
-
- elif mode == "generated":
- # Compare reference vs currently generated
- dir1 = base_dir / "leetcode" / ".example" / problem
- dir2 = base_dir / "leetcode" / problem
- label1, label2 = "Reference", "Generated"
- typer.echo("GENERATED FILES VALIDATION")
-
- if not dir2.exists():
- typer.echo(f"\n❌ ERROR: Generated directory does not exist: {dir2}")
- typer.echo(f"Run: make p-gen PROBLEM={problem}")
- return
-
- typer.echo(f"{label1}: {dir1}")
- typer.echo(f"{label2}: {dir2}")
-
- identical_count = 0
- for filename in files_to_compare:
- file1 = dir1 / filename
- file2 = dir2 / filename
- if compare_files(file1, file2, label1, label2):
- identical_count += 1
-
- typer.echo(f"\n{'='*60}")
- typer.echo(f"SUMMARY: {identical_count}/{len(files_to_compare)} files identical")
- typer.echo("- ✅ = Files identical")
- typer.echo("- ❌ = Differences found or missing files")
-
-
-if __name__ == "__main__":
- typer.run(main)
diff --git a/.amazonq/plans/cookiecutter-template-plan.md b/.amazonq/plans/cookiecutter-template-plan.md
deleted file mode 100644
index ae762c2..0000000
--- a/.amazonq/plans/cookiecutter-template-plan.md
+++ /dev/null
@@ -1,224 +0,0 @@
-# Cookiecutter Template Modernization Plan
-
-## TASK PURPOSE & CRITICAL RULES
-
-**PURPOSE:** Update the cookiecutter template to generate files that exactly match the reference structure in `.templates/leetcode/.example/{{cookiecutter.problem_name}}/`
-
-**REFERENCE DIRECTORIES (NEVER MODIFY - THESE ARE EXAMPLES):**
-
-- `.templates/leetcode/.example/{{cookiecutter.problem_name}}/` - Shows what the template SHOULD generate
-- `leetcode/.example/` - Generated file examples for comparison
-
-**ACTUAL TEMPLATE DIRECTORY (MODIFY THIS):**
-
-- `.templates/leetcode/{{cookiecutter.problem_name}}/` - The cookiecutter template files to update
-
-**WORKFLOW:**
-
-1. Look at `.templates/leetcode/.example/{{cookiecutter.problem_name}}/` to see target structure
-2. Modify `.templates/leetcode/{{cookiecutter.problem_name}}/` to match the reference
-3. Generate with `make p-gen`
-4. Compare generated files vs reference with `make p-validate`
-
-**ERROR PREVENTION:** The template directory does NOT have `.example` in the path!
-
-## Analysis Summary
-
-**Target Structure**: `leetcode/.example/` contains the reference implementation
-**Key Differences Found:**
-
-- `leetcode/.example/` has `__init__.py` files (missing in old template)
-- `leetcode/.example/` uses modern Python syntax (`TreeNode | None` vs `Optional[TreeNode]`)
-- `leetcode/.example/` follows project's coding standards more closely
-- Template must generate files identical to `leetcode/.example/` structure
-
-## Implementation Plan
-
-### 0. Explicit File Content Analysis
-
-- **Tool**: `.amazonq/plan/compare_template_files.py` (already exists - no need to implement)
-- **Usage**:
- - `poetry run python .amazonq/plan/compare_template_files.py generated --problem=PROBLEM_NAME` - Compare generated files vs reference
-- **Analysis**: Line-by-line diff of all file types
-- **Document**: Exact differences and required changes
-- **Verify**: Template variables handle all variations
-
-### 1. Incremental Template Updates (File-by-File Approach)
-
-#### Phase 1: Add `__init__.py`
-
-- **Add**: Empty `__init__.py` file to template
-- **Validate**: `make p-gen` → `make p-validate` → `make lint`
-
-#### Phase 2: Fix `solution.py`
-
-- **Update**: Modern syntax (`TreeNode | None`), clean template logic
-- **Validate**: `make p-gen` → `make p-validate` → `make lint`
-
-#### Phase 3: Fix `tests.py`
-
-- **Update**: Relative imports (`from .solution`), clean structure
-- **Validate**: `make p-gen` → `make p-validate` → `make lint`
-
-#### Phase 4: Fix `README.md`
-
-- **Update**: Clean formatting, proper markdown
-- **Validate**: `make p-gen` → `make p-validate` → `make lint`
-
-#### Phase 5: Fix `playground.ipynb`
-
-- **Update**: Clean cells without execution state
-- **Validate**: `make p-gen` → `make p-validate` → `make lint`
-
-**Benefits**: Isolated debugging, safer progression, easier rollback
-
-### 2. Multi-Problem Type Testing
-
-- **Test Cases**: Ensure template handles all problem types
- - Basic array: `two_sum` (return `list[int]`)
- - Tree: `invert_binary_tree` (return `TreeNode | None`)
- - String: problems returning `str`
- - Boolean: problems returning `bool`
- - No imports vs TreeNode/ListNode imports
-- **Validation**: Each type generates correctly
-
-### 3. Modernize cookiecutter.json Schema
-
-- **Base on**: Existing `.templates/leetcode/.example/examples/` JSON5 files
-- **Ensure**: All template variables are properly defined
-- **Add**: Missing fields found in real examples
-- **Note**: Variable mapping handled by `gen.py` `convert_arrays_to_nested()`
-
-### 4. Update Template Files
-
-#### solution.py
-
-- Use modern type hints (`TreeNode | None` not `Optional[TreeNode]`)
-- Match exact import patterns from real examples
-- Ensure proper TODO placeholder format
-
-#### tests.py
-
-- Follow `@logged_test` decorator pattern
-- Use parametrized pytest structure
-- Match logging format from real examples
-
-#### README.md
-
-- Follow exact format from real examples
-- Include proper problem description formatting
-
-#### playground.ipynb
-
-- Ensure notebook structure matches real examples
-
-### 5. Template Generation Logic
-
-- **File**: `.templates/leetcode/gen.py` (already handles variable mapping)
-- **Integration**: Works with `make p-gen PROBLEM=name` (verified in Makefile)
-- **Update**: Handle new `__init__.py` file
-- **Process**: JSON → `gen.py` → cookiecutter → `leetcode/$(PROBLEM)/`
-
-### 6. Automated Validation System
-
-- **Tool**: Reusable `.amazonq/plan/compare_template_files.py`
-- **Usage**:
- ```bash
- # Validate current template generates correct files
- poetry run python .amazonq/plan/compare_template_files.py generated --problem=invert_binary_tree
- ```
-- **Makefile**: `make p-validate PROBLEM=name` (implemented)
-- **Test**: Template regression testing
-- **Ensure**: `make p-gen` + `make lint` + `make p-test` all pass
-
-### 7. Testing & Validation
-
-- **Test**: Template generation with existing JSON files
-- **Verify**: Generated files match `leetcode/.example/` structure exactly
-- **Compare**: Automated diff against reference files
-- **Ensure**: `make p-gen` works seamlessly
-- **Test**: Recreation process from `.prompt/` files
-- **Validate**: Multi-problem type generation
-
-## Key Template Variables to Ensure
-
-```json
-{
- "problem_name": "snake_case_name",
- "class_name": "PascalCaseName",
- "method_name": "snake_case_method",
- "problem_number": "226",
- "problem_title": "Display Title",
- "difficulty": "Easy|Medium|Hard",
- "topics": "Comma, Separated, Topics",
- "tags": ["grind-75", "blind-75"],
- "problem_description": "Full description",
- "examples": [{"input": "...", "output": "..."}],
- "constraints": "Formatted constraints",
- "parameters": "typed_params: list[int]",
- "return_type": "TreeNode | None",
- "imports": "from leetcode_py import TreeNode",
- "test_cases": [{"args": [...], "expected": ...}]
-}
-```
-
-## Success Criteria
-
-### Phase-by-Phase Validation (File-by-File)
-
-1. ✅ **Phase 1**: `__init__.py` files generated correctly
-2. ✅ **Phase 2**: `solution.py` with modern syntax (`TreeNode | None`)
-3. ✅ **Phase 3**: `tests.py` with relative imports and clean structure
-4. ✅ **Phase 4**: `README.md` with clean formatting
-5. ✅ **Phase 5**: `playground.ipynb` with clean cells
-
-### Multi-Problem Type Validation
-
-5. ✅ Basic problems (array/string) generate correctly
-6. ✅ Tree problems generate correctly
-7. ✅ Different return types handled (`bool`, `int`, `str`, `list`, etc.)
-
-### Automated Validation
-
-8. ✅ Automated diff shows no differences vs `leetcode/.example/`
-9. ✅ `make p-validate` passes for all problem types
-10. ✅ Recreation from `.prompt/` works flawlessly
-11. ✅ All linting passes (`make lint`)
-12. ✅ Tests run successfully (`make p-test`)
-
-## Files to Modify
-
-### Template Files
-
-1. `.templates/leetcode/{{cookiecutter.problem_name}}/`
- - **Add**: `__init__.py` (empty file)
- - **Update**: `solution.py` (modern syntax, imports)
- - **Update**: `tests.py` (match `leetcode/.example/` format)
- - **Update**: `README.md` (match `leetcode/.example/` format)
- - **Update**: `playground.ipynb` (match structure)
-
-### Configuration
-
-2. `.templates/leetcode/cookiecutter.json`
- - Align with JSON5 examples
- - Add missing variables
-
-### Generation Logic
-
-3. `.templates/leetcode/gen.py`
- - Handle `__init__.py` generation
- - Maintain existing variable mapping
-
-### Validation Tools
-
-4. **Reusable**: `.amazonq/plan/compare_template_files.py` (handles both template and generated comparisons)
-5. **New**: Makefile target `make p-validate`
-
-## Risk Mitigation
-
-- **Incremental phases** prevent all-or-nothing failures
-- **Automated validation** catches regressions immediately
-- **Multi-problem testing** ensures template generalization
-- **Explicit file comparison** documents exact requirements
-
-This plan ensures the template generates files that exactly match `leetcode/.example/` while maintaining the robust generation process described in the rules.
diff --git a/.amazonq/rules/problem-creation.md b/.amazonq/rules/problem-creation.md
index 0cc55af..d67a88a 100644
--- a/.amazonq/rules/problem-creation.md
+++ b/.amazonq/rules/problem-creation.md
@@ -29,64 +29,101 @@ Required fields for `.templates/leetcode/json/{problem_name}.json`:
**Reference examples in `.templates/leetcode/examples/` for complete templates:**
- `basic.json5` - Array, string, number problems
+- `design.json5` - Data structure design problems (LRU Cache, etc.)
- `tree.json5` - Binary tree problems
- `linked_list.json5` - Linked list problems
-- `string.json5` - String manipulation problems
- `matrix.json5` - 2D array/matrix problems
-```json
+````json
{
"problem_name": "two_sum",
- "class_name": "TwoSum",
- "method_name": "two_sum",
+ "solution_class_name": "Solution",
"problem_number": "1",
"problem_title": "Two Sum",
"difficulty": "Easy",
"topics": "Array, Hash Table",
"tags": ["grind-75"],
- "problem_description": "Given an array...",
- "examples": [{ "input": "nums = [2,7,11,15], target = 9", "output": "[0,1]" }],
- "constraints": "- 2 <= nums.length <= 10^4",
- "parameters": "nums: list[int], target: int",
- "return_type": "list[int]",
- "dummy_return": "[]",
- "imports": "",
- "test_cases": [{ "args": [[2, 7, 11, 15], 9], "expected": [0, 1] }],
- "param_names": "nums, target, expected",
- "param_names_with_types": "nums: list[int], target: int, expected: list[int]",
- "input_description": "nums={nums}, target={target}",
- "input_params": "nums, target",
- "expected_param": "expected",
- "method_args": "nums, target",
- "test_setup": "",
- "test_logging": "",
- "assertion_code": "assert result == expected",
- "test_input_setup": "nums = [2, 7, 11, 15]\ntarget = 9",
- "expected_output_setup": "expected = [0, 1]"
+ "readme_description": "Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`.",
+ "readme_examples": [
+ {
+ "content": "```\nInput: nums = [2,7,11,15], target = 9\nOutput: [0,1]\n```\n**Explanation:** Because nums[0] + nums[1] == 9, we return [0, 1]."
+ }
+ ],
+ "readme_constraints": "- 2 <= nums.length <= 10^4\n- -10^9 <= nums[i] <= 10^9\n- -10^9 <= target <= 10^9\n- Only one valid answer exists.",
+ "readme_additional": "",
+ "solution_imports": "",
+ "solution_methods": [
+ {
+ "name": "two_sum",
+ "parameters": "nums: list[int], target: int",
+ "return_type": "list[int]",
+ "dummy_return": "[]"
+ }
+ ],
+ "test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
+ "test_class_name": "TwoSum",
+ "test_helper_methods": [
+ {
+ "name": "setup_method",
+ "parameters": "",
+ "body": "self.solution = Solution()"
+ }
+ ],
+ "test_methods": [
+ {
+ "name": "test_two_sum",
+ "parametrize": "nums, target, expected",
+ "parametrize_typed": "nums: list[int], target: int, expected: list[int]",
+ "test_cases": "[([2, 7, 11, 15], 9, [0, 1]), ([3, 2, 4], 6, [1, 2])]",
+ "body": "result = self.solution.two_sum(nums, target)\nassert result == expected"
+ }
+ ],
+ "playground_imports": "from solution import Solution",
+ "playground_test_case": "# Example test case\nnums = [2, 7, 11, 15]\ntarget = 9\nexpected = [0, 1]",
+ "playground_execution": "result = Solution().two_sum(nums, target)\nresult",
+ "playground_assertion": "assert result == expected"
}
-```
+````
## Naming Conventions
- **problem_name**: snake_case (e.g., "two_sum", "valid_palindrome")
-- **class_name**: PascalCase (e.g., "TwoSum", "ValidPalindrome")
+- **solution_class_name**: Usually "Solution", except for design problems (e.g., "LRUCache")
+- **test_class_name**: PascalCase (e.g., "TwoSum", "ValidPalindrome")
- **method_name**: snake_case (e.g., "two_sum", "is_palindrome")
- **parameters**: Use snake_case for all parameter names
+### PascalCase Rules for Properties
+
+When creating JSON properties that use PascalCase (solution_class_name, test_class_name):
+
+- **Acronyms**: Keep all caps (e.g., "LRUCache" not "LruCache")
+- **Roman numerals**: Keep all caps (e.g., "ReverseLinkedListII" not "ReverseLinkedListIi")
+- **Common patterns**: "BST", "DFS", "BFS", "API", "URL", "HTML", "JSON", "XML"
+
## Special Problem Types
### Tree Problems
-- Add `"imports": "from leetcode_py import TreeNode"`
+- Add `"solution_imports": "from leetcode_py import TreeNode"`
- Use `TreeNode | None` for nullable tree parameters
+- Test imports: Include TreeNode in test_imports
- Test setup: `root = TreeNode.from_list(root_list)`
### Linked List Problems
-- Add `"imports": "from leetcode_py import ListNode"`
+- Add `"solution_imports": "from leetcode_py import ListNode"`
- Use `ListNode | None` for nullable list parameters
+- Test imports: Include ListNode in test_imports
- Test setup: `head = ListNode.from_list(head_list)`
+### Design Problems
+
+- Set `"solution_class_name"` to custom class name (e.g., "LRUCache")
+- Multiple methods including `__init__`
+- Complex test setup with operation sequences
+- Import custom class in test_imports
+
## Generation Commands
```bash
diff --git a/.templates/leetcode/cookiecutter.json b/.templates/leetcode/cookiecutter.json
index bf9c13a..adc4fcb 100644
--- a/.templates/leetcode/cookiecutter.json
+++ b/.templates/leetcode/cookiecutter.json
@@ -31,6 +31,7 @@
},
"test_imports": "import pytest\nfrom loguru import logger\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
+ "test_class_name": "TwoSum",
"_test_helper_methods": {
"list": [
{
diff --git a/.templates/leetcode/examples/README.md b/.templates/leetcode/examples/README.md
index 2678b3a..6dbfef8 100644
--- a/.templates/leetcode/examples/README.md
+++ b/.templates/leetcode/examples/README.md
@@ -84,6 +84,14 @@ This directory contains comprehensive JSON5 template examples for different type
- **Test Cases**: String representation of Python data structures
- **Imports**: Include necessary helper classes (TreeNode, ListNode)
+#### PascalCase Naming Rules
+
+For `solution_class_name` and `test_class_name` properties:
+
+- **Acronyms**: Keep all caps ("LRUCache" not "LruCache")
+- **Roman numerals**: Keep all caps ("ReverseLinkedListII" not "ReverseLinkedListIi")
+- **Common patterns**: "BST", "DFS", "BFS", "API", "URL", "HTML", "JSON", "XML"
+
### Template Selection Process
1. Identify problem type from description/title
diff --git a/.templates/leetcode/examples/basic.json5 b/.templates/leetcode/examples/basic.json5
index a1caf73..c00a02f 100644
--- a/.templates/leetcode/examples/basic.json5
+++ b/.templates/leetcode/examples/basic.json5
@@ -1,6 +1,7 @@
{
// Basic problem template - for array, string, number problems
// Example: Container With Most Water, Spiral Matrix
+ // NOTE: PascalCase naming - keep acronyms/Roman numerals ALL CAPS (LRUCache, ReverseLinkedListII)
// === PROBLEM IDENTIFICATION ===
"problem_name": "container_with_most_water", // snake_case: used for directory/file names
@@ -48,6 +49,7 @@
// === TEST CONFIGURATION ===
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
+ "test_class_name": "ContainerWithMostWater", // PascalCase: TestClassName for pytest class
"test_helper_methods": [
{
"name": "setup_method",
diff --git a/.templates/leetcode/examples/design.json5 b/.templates/leetcode/examples/design.json5
index 324dead..9839fc7 100644
--- a/.templates/leetcode/examples/design.json5
+++ b/.templates/leetcode/examples/design.json5
@@ -1,81 +1,83 @@
{
- // Design problem template - for data structure design problems
- // Example: LRU Cache
- // Key differences: Custom class name, multiple methods, complex test setup
+ // Design problem template - for data structure design problems
+ // Example: LRU Cache
+ // Key differences: Custom class name, multiple methods, complex test setup
+ // NOTE: PascalCase naming - keep acronyms/Roman numerals ALL CAPS (LRUCache, ReverseLinkedListII)
- // === PROBLEM IDENTIFICATION ===
- "problem_name": "lru_cache", // snake_case: used for directory/file names
- "solution_class_name": "LRUCache", // IMPORTANT: Custom class name for design problems
- "problem_number": "146", // LeetCode problem number as string
- "problem_title": "LRU Cache", // Exact title from LeetCode
- "difficulty": "Medium", // Easy, Medium, Hard
- "topics": "Hash Table, Linked List, Design, Doubly-Linked List", // Design-related topics
- "tags": ["grind-75"], // Optional: common problem set tags
+ // === PROBLEM IDENTIFICATION ===
+ problem_name: "lru_cache", // snake_case: used for directory/file names
+ solution_class_name: "LRUCache", // IMPORTANT: Custom class name for design problems
+ problem_number: "146", // LeetCode problem number as string
+ problem_title: "LRU Cache", // Exact title from LeetCode
+ difficulty: "Medium", // Easy, Medium, Hard
+ topics: "Hash Table, Linked List, Design, Doubly-Linked List", // Design-related topics
+ tags: ["grind-75"], // Optional: common problem set tags
- // === README CONTENT ===
- // IMPORTANT: Preserve rich HTML content from LeetCode including:
- // - Code snippets with backticks: `code`
- // - Bold text: **bold** or bold
- // - Italic text: *italic* or italic
- // - Images:
tags with proper src and styling
- // - HTML formatting:
,
,
,
,