Skip to content

Conversation

@BrianLusina
Copy link
Owner

@BrianLusina BrianLusina commented Jan 15, 2026

Describe your change:

Counting bits

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • [x ] All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.
  • If this pull request resolves one or more open issues then the commit message contains Fixes: #{$ISSUE_NO}.

Summary by CodeRabbit

  • New Features

    • Added Counting Bits, K Closest Elements, Merge K Sorted Lists, and Paint House algorithms; Climb Stairs moved into Dynamic Programming.
  • Documentation

    • Added problem descriptions, examples, constraints, recurrence/approach notes, and complexity for the new entries.
  • Tests

    • Added parameterized unit tests covering each new algorithm.

✏️ Tip: You can customize this high-level summary in your review settings.

@BrianLusina BrianLusina self-assigned this Jan 15, 2026
@BrianLusina BrianLusina added enhancement Algorithm Algorithm Problem Bit Manipulation Bit Manipulation Dynamic Programming Dynamic Programming algorithm labels Jan 15, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

📝 Walkthrough

Walkthrough

Adds Counting Bits, K Closest Elements, Merge K Sorted Lists, and Paint House algorithm modules with READMEs and unit tests; implements count_bits, k_closest, and merge_k_lists functions; updates DIRECTORY.md and removes a Climb Stairs entry from Puzzles.

Changes

Cohort / File(s) Summary
Directory Index
DIRECTORY.md
Updated index: added Counting Bits, K Closest Elements, Merge K Sorted Lists, and Paint House; removed Climb Stairs from Puzzles (+10/-2).
Counting Bits (DP)
algorithms/dynamic_programming/countingbits/README.md, algorithms/dynamic_programming/countingbits/__init__.py, algorithms/dynamic_programming/countingbits/test_counting_bits.py
New bottom-up DP count_bits(n: int) -> List[int], README with problem/recurrence, and parameterized tests (+78/+20/+24 lines).
K Closest Elements (Heap)
algorithms/heap/kclosestelements/README.md, algorithms/heap/kclosestelements/__init__.py, algorithms/heap/kclosestelements/test_find_k_closest_elements.py
New k_closest(nums: List[int], k: int, target: int) using a max-heap simulation, README examples, and tests (+29/+18/+26 lines).
Merge K Sorted Lists (Heap)
algorithms/heap/mergeksortedlists/README.md, algorithms/heap/mergeksortedlists/__init__.py, algorithms/heap/mergeksortedlists/test_merge_k_sorted_lists.py
New merge_k_lists(lists: List[List[int]]) -> List[int] using a min-heap, README, and parameterized tests (+18/+53/+24 lines).
Paint House (DP)
algorithms/dynamic_programming/painthouse/README.md, algorithms/dynamic_programming/painthouse/__init__.py, algorithms/dynamic_programming/painthouse/test_min_cost_to_paint_houses.py
New min_cost_to_paint_houses_alternate_colors(costs: List[List[int]]) -> int, README describing space-optimized DP, and tests (+107/+43/+20 lines).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through docs and tests anew,
Bits counted, heaps sorted true,
Paint and lists all in a row,
I twitched my nose and watched them grow,
Carrots for each passing view!

🚥 Pre-merge checks | ❌ 3
❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title only references counting bits but the PR includes multiple additional algorithms (k closest elements, merge k sorted lists, paint house) beyond what the title indicates. Update the title to accurately reflect all changes, such as 'feat(algorithms): add counting bits, k closest elements, merge k sorted lists, and paint house' or split into separate PRs per algorithm.
Description check ⚠️ Warning The description provides minimal detail ('Counting bits') and the checklist has a formatting typo ('* [x ]' instead of '* [x]'). More critically, the PR description does not reflect all the changes present in the changeset. Provide a detailed description of all changes (counting bits, k closest elements, merge k sorted lists, paint house) with explanation of each addition, or follow the guideline to 'open separate PRs for separate algorithms.'
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@algorithms/dynamic_programming/countingbits/README.md`:
- Around line 54-56: The sentence starting "in the binary representation of i is
that number plus 1" is incomplete; rewrite it to include the missing subject so
it reads clearly (e.g., "The number of 1s in the binary representation of i is
that number plus 1 if the rightmost bit is 1.") — update the README.md sentence
that references the variable i and the rightmost bit to explicitly state "the
number of 1s" (or equivalent) and ensure the following sentence about checking
odd/even ties back to that clarified phrasing.

In `@algorithms/heap/kclosestelements/README.md`:
- Around line 3-5: Fix the minor grammar in the problem description: change the
phrase "Return these elements in array" to "Return these elements in an array"
in the README description (the sentence that starts "Return these elements...")
so the wording is correct and reads "Return these elements in an array, sorted
in ascending order."

In `@algorithms/heap/mergeksortedlists/__init__.py`:
- Around line 45-46: Fix the typo in the inline comment that reads "We check if
the element index is less than the current list it can be found in. This means
that there are still other elements withing this list" by changing "withing" to
"within" so the comment now reads "...there are still other elements within this
list"; update the comment near the merge logic in mergeksortedlists/__init__.py
where that sentence appears.

In `@algorithms/heap/mergeksortedlists/test_merge_k_sorted_lists.py`:
- Line 16: Rename the test class from MegeKListsTestCase to MergeKListsTestCase:
update the class declaration "class MegeKListsTestCase(unittest.TestCase):" to
"class MergeKListsTestCase(unittest.TestCase):" and update any references to
MegeKListsTestCase within the test file (or other test modules) to the corrected
name so unittest discovery and any imports/subclasses continue to work.
🧹 Nitpick comments (4)
algorithms/dynamic_programming/countingbits/README.md (1)

19-19: Add language specifier to fenced code block.

The code block is missing a language specifier. For consistency with Example 1 (line 8), add text after the opening fence.

Proposed fix
-```
+```text
 Example 2:
algorithms/dynamic_programming/countingbits/__init__.py (1)

16-17: Minor grammar fix in comment.

The comment is slightly unclear. Consider rephrasing for better readability.

Proposed fix
-        # this can also be solved as which is faster in Python
+        # Alternative using bitwise ops (may be faster):
         # dp[i] = dp[i >> 1] + (i & 1)
algorithms/heap/kclosestelements/__init__.py (1)

5-5: Add return type annotation and docstring.

The function is missing a return type annotation and docstring for consistency with the codebase (e.g., merge_k_lists in this PR has both).

♻️ Suggested improvement
-def k_closest(nums: List[int], k: int, target: int):
+def k_closest(nums: List[int], k: int, target: int) -> List[int]:
+    """
+    Returns the k elements from nums closest to target.
+    Args:
+        nums: List of integers
+        k: Number of closest elements to return
+        target: Target value to measure distance from
+    Returns:
+        List of k integers closest to target, sorted in ascending order
+    """
     heap = []
algorithms/heap/kclosestelements/test_find_k_closest_elements.py (1)

6-13: Consider adding edge case tests.

The current test cases cover good scenarios, but consider adding edge cases for robustness:

  • Empty array: ([], 0, 5, [])
  • k equals array length: ([1, 2, 3], 3, 2, [1, 2, 3])
  • Single element: ([5], 1, 10, [5])
  • Negative numbers: ([-5, -3, 0, 2], 2, -1, [-3, 0])
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6eb579 and 8722c3a.

⛔ Files ignored due to path filters (12)
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_1.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_10.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_11.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_12.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_2.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_3.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_4.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_5.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_6.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_7.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_8.png is excluded by !**/*.png
  • algorithms/dynamic_programming/countingbits/images/solutions/counting_bits_solution_9.png is excluded by !**/*.png
📒 Files selected for processing (13)
  • DIRECTORY.md
  • algorithms/dynamic_programming/climb_stairs/README.md
  • algorithms/dynamic_programming/climb_stairs/__init__.py
  • algorithms/dynamic_programming/climb_stairs/test_climb_stairs.py
  • algorithms/dynamic_programming/countingbits/README.md
  • algorithms/dynamic_programming/countingbits/__init__.py
  • algorithms/dynamic_programming/countingbits/test_counting_bits.py
  • algorithms/heap/kclosestelements/README.md
  • algorithms/heap/kclosestelements/__init__.py
  • algorithms/heap/kclosestelements/test_find_k_closest_elements.py
  • algorithms/heap/mergeksortedlists/README.md
  • algorithms/heap/mergeksortedlists/__init__.py
  • algorithms/heap/mergeksortedlists/test_merge_k_sorted_lists.py
🧰 Additional context used
🧬 Code graph analysis (2)
algorithms/dynamic_programming/countingbits/test_counting_bits.py (1)
algorithms/dynamic_programming/countingbits/__init__.py (1)
  • count_bits (4-20)
algorithms/heap/kclosestelements/test_find_k_closest_elements.py (1)
algorithms/heap/kclosestelements/__init__.py (1)
  • k_closest (5-18)
🪛 LanguageTool
algorithms/dynamic_programming/countingbits/README.md

[style] ~67-~67: Using many exclamation marks might seem excessive (in this case: 10 exclamation marks for a text that’s 2311 characters long)
Context: ...solutions/counting_bits_solution_1.png) Solution 2 Solution 3 Solution 4 Solution 5 Solution 6 Solution 7 Solution 8 Solution 9 Solution 10 ![Solution 11](./images/solutions/countin...

(EN_EXCESSIVE_EXCLAMATION)

🪛 markdownlint-cli2 (0.18.1)
algorithms/dynamic_programming/countingbits/README.md

19-19: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

DIRECTORY.md

58-58: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


59-59: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


60-60: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


61-61: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


145-145: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


146-146: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


147-147: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


148-148: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


149-149: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


150-150: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


151-151: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


152-152: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


153-153: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


154-154: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)

🔇 Additional comments (12)
algorithms/dynamic_programming/countingbits/__init__.py (1)

4-20: LGTM!

The dynamic programming implementation is correct and efficient:

  • O(n) time and space complexity
  • Properly handles the base case (dp[0] = 0)
  • The recurrence relation dp[i] = dp[i // 2] + (i % 2) correctly leverages the relationship between a number and its right-shifted form
algorithms/dynamic_programming/countingbits/test_counting_bits.py (2)

6-13: LGTM!

Good test coverage with parameterized tests:

  • Edge case n=0 is covered
  • Multiple input sizes tested
  • Expected values are correct (verified against binary representations)

16-20: LGTM!

Clean test structure using parameterized.expand for data-driven testing. The assertion correctly compares expected and actual results.

DIRECTORY.md (1)

58-61: LGTM!

The directory structure updates correctly reflect the new algorithm implementations. The static analysis indentation warnings (MD007) are false positives — the indentation style used here is consistent with the rest of the file throughout.

Also applies to: 145-146, 153-154

algorithms/heap/kclosestelements/__init__.py (1)

8-18: LGTM!

The max-heap approach using negative differences is a clean and efficient O(n log k) solution. The logic correctly maintains the k closest elements and returns them sorted.

algorithms/heap/mergeksortedlists/__init__.py (2)

14-20: LGTM!

Good defensive programming with proper input validation handling both [] and [[]] cases.


30-53: LGTM!

Clean implementation of the k-way merge pattern. The heap tuple structure (value, list_index, element_index) correctly prioritizes by value, and the logic properly tracks positions within each list.

algorithms/heap/mergeksortedlists/test_merge_k_sorted_lists.py (1)

6-13: LGTM!

Good test coverage including edge cases (empty inputs, single list) and scenarios with negative numbers and duplicates.

algorithms/heap/mergeksortedlists/README.md (1)

1-18: LGTM!

Clear documentation with a helpful example showing both array and linked-list notation. The implementation uses arrays (List[List[int]]) which is a valid representation for this problem.

algorithms/heap/kclosestelements/README.md (1)

7-29: Documentation examples are clear and helpful.

The examples effectively illustrate the problem with both a detailed explanation (first example) and a concise output (second example).

algorithms/heap/kclosestelements/test_find_k_closest_elements.py (2)

1-4: LGTM!

Imports are appropriate. Using parameterized for test case expansion is a clean approach for testing multiple inputs.


16-22: Test implementation is clean and follows best practices.

Good use of parameterized.expand for data-driven testing. The assertion correctly compares expected vs actual results.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

BrianLusina and others added 3 commits January 15, 2026 17:38
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@github-actions github-actions bot force-pushed the feat/algorithms-dynamic-programming branch from eb80355 to dce0b1c Compare January 15, 2026 14:39
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@algorithms/heap/kclosestelements/README.md`:
- Around line 17-18: Remove the redundant "Explanation:" text in the paragraph
that begins "Explanation: -1 is 2 away..." so it doesn't duplicate the section
header "Explanation"—keep the section header "Explanation" and change the
paragraph to start directly with "-1 is 2 away from 1, 0 is 1 away from 1, and 1
is 0 away from 1. All other elements are more than 2 away."
🧹 Nitpick comments (1)
algorithms/heap/kclosestelements/README.md (1)

14-27: Standardize "Output" formatting.

The first example uses "Output" without a colon (line 14), while the second example uses "Output:" with a colon (line 27). Consider standardizing this for consistency.

📝 Suggested fix
 
-Output
+Output:
 [-1, 0, 1]
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8722c3a and dce0b1c.

📒 Files selected for processing (3)
  • algorithms/heap/kclosestelements/README.md
  • algorithms/heap/mergeksortedlists/__init__.py
  • algorithms/heap/mergeksortedlists/test_merge_k_sorted_lists.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • algorithms/heap/mergeksortedlists/test_merge_k_sorted_lists.py
  • algorithms/heap/mergeksortedlists/init.py

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
DIRECTORY.md (1)

58-77: PR scope exceeds the stated objective.

The PR title indicates this adds only "counting bits", but the changes add at least 5 algorithm modules:

  1. Climb Stairs (lines 58-59)
  2. Counting Bits (lines 60-61)
  3. Paint House (lines 76-77)
  4. K Closest Elements (lines 147-148)
  5. Merge K Sorted Lists (lines 155-156)

Additionally, the PR description claims "single algorithm file changed", but this appears to add multiple distinct algorithms across different categories (Dynamic Programming and Heap).

Consider splitting this into separate PRs for each algorithm to:

  • Make reviews more focused and manageable
  • Enable easier rollback if issues arise
  • Improve git history clarity
  • Follow the single-responsibility principle

Also applies to: 147-156

🤖 Fix all issues with AI agents
In `@algorithms/dynamic_programming/painthouse/README.md`:
- Around line 75-85: Fix the typos in the README's recurrence explanation:
change `prev_min_cost_gree` to `prev_min_cost_green` in the red calculation,
change the green-line suffix `+ cost_blue` to `+ cost_green`, and correct
`prev_mins_cost_red` to `prev_min_cost_red`; ensure all three lines consistently
reference prev_min_cost_red, prev_min_cost_blue, prev_min_cost_green and their
corresponding cost_red, cost_blue, cost_green symbols.

In `@DIRECTORY.md`:
- Around line 147-148: Update the inconsistent Heap section entries: rename the
headings/text "Kclosestelements" to "K Closest Elements" and "Mergeksortedlists"
to "Merge K Sorted Lists" wherever they appear (including the two occurrences
around the referenced lines), and update the corresponding Markdown link text
and directory/file paths to follow the space-separated heading and snake_case
filename convention (e.g., k_closest_elements and merge_k_sorted_lists) so link
targets and displayed names match the repository naming style.
- Around line 76-77: Update the directory entry "Painthouse" to the
space-separated, consistent name "Paint House" (or "Paint Houses" to match
test_min_cost_to_paint_houses.py) and rename the corresponding folder identifier
from painthouse to paint_house so it follows the project's naming convention;
update any references to the test file test_min_cost_to_paint_houses.py or its
link text to match the new display name to avoid mismatches.
- Around line 60-61: Rename the "Countingbits" entry to "Counting Bits" to match
the space-separated naming used by other Dynamic Programming entries, change the
nested list indentation to 2 spaces (not 4-6) so it aligns with Markdown best
practices, and update the directory/module name from countingbits to
counting_bits (and the repo link path if necessary) to follow Python naming
conventions; ensure the link text and target reflect the new names.
🧹 Nitpick comments (1)
algorithms/dynamic_programming/painthouse/__init__.py (1)

4-14: Consider adding doctests per PR checklist.

The PR checklist indicates that "all functions include doctests that pass automated testing." This function lacks doctests. Adding doctests would also serve as inline documentation.

📝 Suggested doctest examples
 def min_cost_to_paint_houses_alternate_colors(costs: List[List[int]]) -> int:
     """
     Finds the minimum cost to paint houses in a street without repeating colors consecutively
     Args:
         costs(list): Costs of painting houses as a 2D list
     Returns:
         int: minimum cost of painting houses
+
+    >>> min_cost_to_paint_houses_alternate_colors([[8, 4, 15], [10, 7, 3], [6, 9, 12]])
+    13
+    >>> min_cost_to_paint_houses_alternate_colors([[5, 8, 6], [19, 14, 13], [7, 5, 12], [14, 5, 9]])
+    30
+    >>> min_cost_to_paint_houses_alternate_colors([])
+    0
     """
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 434692c and 28a2794.

📒 Files selected for processing (4)
  • DIRECTORY.md
  • algorithms/dynamic_programming/painthouse/README.md
  • algorithms/dynamic_programming/painthouse/__init__.py
  • algorithms/dynamic_programming/painthouse/test_min_cost_to_paint_houses.py
🧰 Additional context used
🧬 Code graph analysis (1)
algorithms/dynamic_programming/painthouse/test_min_cost_to_paint_houses.py (1)
algorithms/dynamic_programming/painthouse/__init__.py (1)
  • min_cost_to_paint_houses_alternate_colors (4-43)
🪛 markdownlint-cli2 (0.18.1)
algorithms/dynamic_programming/painthouse/README.md

5-5: Reference links and images should use a label that is defined
Missing link or image reference definition: "0"

(MD052, reference-links-images)


6-6: Reference links and images should use a label that is defined
Missing link or image reference definition: "1"

(MD052, reference-links-images)


7-7: Reference links and images should use a label that is defined
Missing link or image reference definition: "2"

(MD052, reference-links-images)


15-15: Reference links and images should use a label that is defined
Missing link or image reference definition: "j"

(MD052, reference-links-images)

DIRECTORY.md

58-58: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


59-59: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


60-60: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


61-61: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


76-76: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


77-77: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


147-147: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


148-148: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


149-149: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


150-150: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


151-151: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


152-152: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


153-153: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


154-154: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)


155-155: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


156-156: Unordered list indentation
Expected: 4; Actual: 6

(MD007, ul-indent)

🔇 Additional comments (3)
algorithms/dynamic_programming/painthouse/test_min_cost_to_paint_houses.py (1)

1-20: LGTM!

The test file is well-structured with parameterized test cases that match the examples in the README. The use of parameterized.expand for data-driven testing is appropriate.

algorithms/dynamic_programming/painthouse/__init__.py (1)

25-43: LGTM!

The DP implementation is correct and space-efficient. The algorithm properly ensures no two adjacent houses share the same color by computing each current cost as the minimum of the two non-matching previous costs plus the current color cost.

algorithms/dynamic_programming/painthouse/README.md (1)

1-16: Documentation structure looks good.

The problem statement, constraints, and examples are well-documented. Note: The static analysis warnings about reference links on lines 5-7 and 15 are false positives—[0], [1], [2], and [j] are array index notation, not Markdown reference links.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@BrianLusina BrianLusina merged commit c061165 into main Jan 16, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Algorithm Algorithm Problem Bit Manipulation Bit Manipulation Dynamic Programming Dynamic Programming algorithm enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants