feat(algorithms, dynamic-programming): house robber 3#185
Conversation
📝 WalkthroughWalkthroughThis pull request introduces House Robber III, a binary tree variant of the classic house robber dynamic programming problem, with three solution approaches (recursion, top-down DP with memoization, bottom-up DP), comprehensive documentation detailing constraints and complexity analyses, and refactored parameterized test suite. Changes
Sequence DiagramsequenceDiagram
participant Client
participant rob_iii_recursion
participant BinaryTreeNode
participant rob_iii_dp_top_down
participant Memo
Client->>rob_iii_recursion: Call with root
rob_iii_recursion->>BinaryTreeNode: Visit node
alt Has left child
rob_iii_recursion->>rob_iii_recursion: Recursively visit left
end
alt Has right child
rob_iii_recursion->>rob_iii_recursion: Recursively visit right
end
rob_iii_recursion-->>Client: Return max robbery amount
Client->>rob_iii_dp_top_down: Call with root
rob_iii_dp_top_down->>Memo: Check if node memoised
alt Memoised
Memo-->>rob_iii_dp_top_down: Return cached result
else Not memoised
rob_iii_dp_top_down->>BinaryTreeNode: Visit node
rob_iii_dp_top_down->>rob_iii_dp_top_down: Recursively visit children
rob_iii_dp_top_down->>Memo: Store result
end
rob_iii_dp_top_down-->>Client: Return max robbery amount
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
algorithms/dynamic_programming/house_robber/test_house_robber.py (1)
20-127: Prefer factory-built trees per case to avoid shared mutable fixtures.
ROB_III_TEST_CASEScurrently reuses the sameBinaryTreeNodeinstances across multiple tests. Generating a fresh tree per case will keep tests isolated and future-proof against accidental node mutation.🧪 Suggested pattern
-ROB_III_TEST_CASES = [ - (BinaryTreeNode(...), 7), -] +ROB_III_TEST_CASES = [ + (lambda: BinaryTreeNode(...), 7), +] `@parameterized.expand`(ROB_III_TEST_CASES) -def test_rob_iii_recursion(self, root: BinaryTreeNode, expected: int): +def test_rob_iii_recursion(self, root_factory, expected: int): + root = root_factory() actual = rob_iii_recursion(root)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@algorithms/dynamic_programming/house_robber/test_house_robber.py` around lines 20 - 127, ROB_III_TEST_CASES currently constructs BinaryTreeNode objects once and reuses those same node instances across cases; instead, make each case produce a fresh tree by replacing concrete BinaryTreeNode constructions with factory callables (e.g., lambdas or small helper functions) that return a new BinaryTreeNode root when invoked. Update ROB_III_TEST_CASES to store tuples like (lambda: BinaryTreeNode(...), expected) and change the test harness to call the factory before passing the tree into the functions under test so each run gets a newly-built tree; reference the ROB_III_TEST_CASES symbol and BinaryTreeNode constructors when implementing the factories.algorithms/dynamic_programming/house_robber/README.md (1)
36-36: Polish wording for consistency in two places.Line 36: use “directly linked” (no hyphen).
Line 79: use “Top-Down” to match the section heading style.✏️ Suggested markdown edits
- in this place form a binary tree. It will automatically contact the police if two directly-linked houses were broken + in this place form a binary tree. It will automatically contact the police if two directly linked houses were broken - 2. [Dynamic Programming(Memoization) - Top Down Approach](`#dynamic-programmingmemoization-top-down-approach`) + 2. [Dynamic Programming(Memoization) - Top-Down Approach](`#dynamic-programmingmemoization-top-down-approach`)Also applies to: 79-79
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@algorithms/dynamic_programming/house_robber/README.md` at line 36, Update the wording for consistency: replace the hyphenated phrase "directly-linked" with "directly linked" in the sentence "It will automatically contact the police if two directly-linked houses were broken" (look for that exact sentence in the README) and change the section/phrase "Top down" to title-case "Top-Down" to match the section heading style (search for "Top down" around the Top-Down section header).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@algorithms/dynamic_programming/house_robber/__init__.py`:
- Around line 17-80: All three functions (rob_iii_recursion,
rob_iii_dynamic_programming_top_down, rob_iii_dynamic_programming_bottom_up) can
crash on skewed trees due to Python recursion limits; add a recursion-depth
guard and a non-recursive fallback: detect current recursion depth (pass a depth
counter or check sys.getrecursionlimit() vs current frame depth) and when depth
approaches the limit (e.g. > 900) switch to an iterative implementation that
uses an explicit stack/post-order traversal with a memo dict (key by node id or
node reference) to compute the same include/exclude values (for bottom_up
compute [include, exclude] per node iteratively; for top_down perform memoized
DFS with an explicit stack or simulate recursion using a stack of frames), and
have rob_iii_recursion call the top_down or bottom_up iterative fallback so all
three handle deep/skewed trees without RecursionError.
---
Nitpick comments:
In `@algorithms/dynamic_programming/house_robber/README.md`:
- Line 36: Update the wording for consistency: replace the hyphenated phrase
"directly-linked" with "directly linked" in the sentence "It will automatically
contact the police if two directly-linked houses were broken" (look for that
exact sentence in the README) and change the section/phrase "Top down" to
title-case "Top-Down" to match the section heading style (search for "Top down"
around the Top-Down section header).
In `@algorithms/dynamic_programming/house_robber/test_house_robber.py`:
- Around line 20-127: ROB_III_TEST_CASES currently constructs BinaryTreeNode
objects once and reuses those same node instances across cases; instead, make
each case produce a fresh tree by replacing concrete BinaryTreeNode
constructions with factory callables (e.g., lambdas or small helper functions)
that return a new BinaryTreeNode root when invoked. Update ROB_III_TEST_CASES to
store tuples like (lambda: BinaryTreeNode(...), expected) and change the test
harness to call the factory before passing the tree into the functions under
test so each run gets a newly-built tree; reference the ROB_III_TEST_CASES
symbol and BinaryTreeNode constructors when implementing the factories.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (20)
algorithms/dynamic_programming/house_robber/images/examples/house_robber_3_example_1.1.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/examples/house_robber_3_example_1.2.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/examples/house_robber_3_example_1.3.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/examples/house_robber_3_example_1.4.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/examples/house_robber_3_example_1.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/examples/house_robber_3_example_2.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/examples/house_robber_3_example_3.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/examples/house_robber_3_example_4.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_1.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_10.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_11.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_12.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_2.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_3.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_4.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_5.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_6.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_7.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_8.pngis excluded by!**/*.pngalgorithms/dynamic_programming/house_robber/images/solutions/house_robber_iii_solution_dp_bottom_up_9.pngis excluded by!**/*.png
📒 Files selected for processing (3)
algorithms/dynamic_programming/house_robber/README.mdalgorithms/dynamic_programming/house_robber/__init__.pyalgorithms/dynamic_programming/house_robber/test_house_robber.py
Describe your change:
House robber 3 dynamic programming with binary tree
Checklist:
Fixes: #{$ISSUE_NO}.Summary by CodeRabbit
Release Notes
New Features
Documentation
Tests