Skip to content

feat(algorithms hash table): ransom note#160

Merged
BrianLusina merged 3 commits into
mainfrom
feat/algorithms-hash-table-ransom-note
Jan 23, 2026
Merged

feat(algorithms hash table): ransom note#160
BrianLusina merged 3 commits into
mainfrom
feat/algorithms-hash-table-ransom-note

Conversation

@BrianLusina
Copy link
Copy Markdown
Owner

@BrianLusina BrianLusina commented Jan 23, 2026

Describe your change:

Ransom note implementation with a Hash table

  • 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.
  • 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 a Hash Table section with a Ransom Note algorithm and two working implementations
    • Added a utility to remove the nth node from the end of a linked list
  • Documentation

    • Added comprehensive Ransom Note README with problem description, examples, solution approach, and complexity analysis
  • Tests

    • Added test suite covering multiple Ransom Note scenarios
  • Improvements

    • Strengthened type annotations for circular linked list APIs and updated tests to match API changes

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

@BrianLusina BrianLusina self-assigned this Jan 23, 2026
@BrianLusina BrianLusina added enhancement Algorithm Algorithm Problem Datastructures Datastructures Documentation Documentation Updates Strings Hash Map Hash Map Data structure labels Jan 23, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 23, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds a new "Ransom Note" hash-table algorithm (docs, two implementations, tests), updates circular linked list type hints to use CircularNode and adjusts related tests, and adds a remove_nth_from_end linked-list utility.

Changes

Cohort / File(s) Summary
Hash Table - Ransom Note
DIRECTORY.md, algorithms/hash_table/ransom_note/README.md, algorithms/hash_table/ransom_note/__init__.py, algorithms/hash_table/ransom_note/test_ransom_note.py
New problem entry and README; two implementations added (can_construct using collections.Counter, can_construct_2 using manual freq dict); parameterized tests added.
Circular Linked List Type Refinements
datastructures/linked_lists/circular/__init__.py, datastructures/linked_lists/circular/test_circular_linked_list.py
Replaced generic Node type hints with CircularNode across public methods; split_list signature/return adjusted; tests updated to unpack composite return and assert on heads.
Linked List Utilities
datastructures/linked_lists/linked_list_utils.py
Added remove_nth_from_end(head: Optional[Node], n: int) -> Optional[Node] using two-pointer technique with edge-case handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I counted letters, one by one, to make a note so sly,
CircularNodes now sharper, hops typed neat and spry,
Pointers pull the nth from end with a gentle sway,
The directory blooms with problems to play! 📚✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding a ransom note algorithm implementation using a hash table approach.
Description check ✅ Passed The PR description is complete with all required sections filled out and all checklist items marked as addressed, demonstrating compliance with repository contribution guidelines.

✏️ 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
Copy Markdown
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

Caution

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

⚠️ Outside diff range comments (2)
datastructures/linked_lists/linked_list_utils.py (1)

150-173: Validate n to avoid runtime errors for out‑of‑range inputs.

n > length currently raises an AttributeError, and n <= 0 removes the tail unintentionally. Add explicit bounds checks to make the utility safe.

🛠️ Proposed fix
 def remove_nth_from_end(head: Optional[Node], n: int) -> Optional[Node]:
@@
     if not head:
         return head
+    if n <= 0:
+        raise ValueError("n must be >= 1")
@@
-    for _ in range(n):
-        fast = fast.next
+    for _ in range(n):
+        if not fast:
+            raise ValueError("n is larger than the list length")
+        fast = fast.next
datastructures/linked_lists/circular/__init__.py (1)

201-236: split_list return type/behavior is inconsistent with the docstring.

The method returns (self.head, second_list) even though the docstring describes two circular linked lists; the type hint also suggests nodes while second_list is a CircularLinkedList. This mismatch can break callers and tests. Return list objects instead (and update tests accordingly).

🛠️ Proposed fix
-    def split_list(self) -> Optional[Tuple[CircularNode, Optional[CircularNode]]]:
+    def split_list(
+        self,
+    ) -> Optional[Tuple["CircularLinkedList", Optional["CircularLinkedList"]]]:
@@
-        if size == 1:
-            return self.head, None
+        if size == 1:
+            return self, None
@@
-        return self.head, second_list
+        return self, second_list
🤖 Fix all issues with AI agents
In `@DIRECTORY.md`:
- Around line 160-162: The Markdown list indentation for the "Hash Table"
section is off for MD007: change the three-level block so the top-level bullet
"* Hash Table" starts at 0 spaces, the nested "* Ransom Note" at 2 spaces, and
the link item "[Test Ransom Note](...)" at 4 spaces; update those three lines in
DIRECTORY.md accordingly to follow the 0/2/4 indentation convention.
🧹 Nitpick comments (2)
algorithms/hash_table/ransom_note/__init__.py (1)

32-51: Simplify can_construct by dropping the redundant count.

You can return True after the loop since any failure already returns False. This reduces state and keeps the logic tight.

♻️ Proposed simplification
-    # Count the number of letters in the ransom note. This will be used to track how many letters are left when constructing
-    # the ransom note from the letters in the magazine
-    count = len(ransom_note)
@@
-        occurrences[letter] -= 1
-        count -= 1
+        occurrences[letter] -= 1
@@
-    return count == 0
+    return True
algorithms/hash_table/ransom_note/test_ransom_note.py (1)

5-14: Consider adding edge case tests and named parameters for better diagnostics.

The test cases cover core scenarios well, but consider:

  1. Adding descriptive names to test cases for clearer failure messages
  2. Adding edge cases for empty strings (empty ransom_note, empty magazine)

Note: The two implementations behave differently for edge cases—can_construct returns False for an empty magazine even when ransom_note is empty, while can_construct_2 returns True for an empty ransom_note. You may want to align this behavior and add explicit tests.

♻️ Suggested improvements
 RANSOM_NOTE_TEST_CASES = [
-    ("codinginterviewquestions", "aboincsdefoetingvqtniewonoregessnutins", True),
-    ("code", "coingd", False),
-    ("codinginterview", "vieewidingcodinter", True),
-    ("program", "programming", True),
-    ("me", "meme", True),
-    ("a", "b", False),
-    ("aa", "ab", False),
-    ("aa", "aab", True),
+    ("long_note_success", "codinginterviewquestions", "aboincsdefoetingvqtniewonoregessnutins", True),
+    ("missing_letter", "code", "coingd", False),
+    ("shuffled_letters", "codinginterview", "vieewidingcodinter", True),
+    ("subset_of_magazine", "program", "programming", True),
+    ("repeated_letters", "me", "meme", True),
+    ("single_char_mismatch", "a", "b", False),
+    ("insufficient_repeated_char", "aa", "ab", False),
+    ("sufficient_repeated_char", "aa", "aab", True),
+    ("empty_ransom_note", "", "abc", True),
+    ("empty_magazine", "a", "", False),
 ]

Comment thread DIRECTORY.md
@BrianLusina BrianLusina merged commit ef92194 into main Jan 23, 2026
4 of 7 checks passed
@BrianLusina BrianLusina deleted the feat/algorithms-hash-table-ransom-note branch February 20, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Algorithm Algorithm Problem Datastructures Datastructures Documentation Documentation Updates enhancement Hash Map Hash Map Data structure Strings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant