Skip to content

Conversation

nzamulov
Copy link
Contributor

Challenge 23 Solution

Submitted by: @nzamulov
Challenge: Challenge 23

Description

This PR contains my solution for Challenge 23.

Changes

  • Added solution file to challenge-23/submissions/nzamulov/solution-template.go

Testing

  • Solution passes all test cases
  • Code follows Go best practices

Thank you for reviewing my submission! 🚀

Copy link

coderabbitai bot commented Oct 11, 2025

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title clearly summarizes the primary change by indicating that it adds a solution for Challenge 23 authored by nzamulov, which directly corresponds to the files added in this changeset.
Description Check ✅ Passed The pull request description succinctly outlines that this PR contains the solution file for Challenge 23, references the exact file added, and notes testing and adherence to best practices, all of which are directly related to the changeset.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 421a787 and 63da7e7.

📒 Files selected for processing (1)
  • challenge-23/submissions/nzamulov/solution-template.go (1 hunks)
🔇 Additional comments (5)
challenge-23/submissions/nzamulov/solution-template.go (5)

1-5: LGTM!

Standard package and import declarations are appropriate for this challenge submission.


7-39: LGTM!

The test harness is well-structured with diverse test cases covering different scenarios (overlapping patterns, multiple matches, etc.). The output format clearly shows results from all three algorithms for easy comparison.


43-54: Algorithm implementation is correct.

The naive pattern matching logic correctly handles empty patterns and performs exhaustive substring comparison. The boundary check i+len(pattern)-1 < len(text) safely prevents out-of-bounds access.


56-82: KMP implementation using concatenation approach is correct.

The algorithm correctly:

  • Builds the prefix array over pattern + "#" + text
  • Identifies matches where pi[i] == len(pattern)
  • Calculates start positions using i - 2*len(pattern), which properly accounts for the concatenated structure

The implementation efficiently finds all pattern occurrences in O(n+m) time.


84-122: Rabin-Karp implementation is correct and well-designed.

The algorithm properly implements polynomial rolling hash with:

  • Standard constants (base=31, mod=1e7+7) for good hash distribution
  • Precomputed power and prefix hash arrays for O(1) window hash calculation
  • Position-weighted hash comparison: curr_ht == (hp*pows[i])%mod
  • Substring verification to eliminate hash collision false positives (line 117)

Edge cases are handled correctly, including empty patterns and patterns longer than text.


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

@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

🧹 Nitpick comments (1)
challenge-23/submissions/nzamulov/solution-template.go (1)

84-85: Consider scoping constants locally or using more descriptive names.

The global constants p and mod could be moved inside RabinKarpSearch or given more descriptive names like rabinKarpBase and rabinKarpMod to clarify their purpose and scope.

Example refactor:

-const p int64 = 31
-const mod = int64(1e7 + 7)
-
 // RabinKarpSearch implements the Rabin-Karp algorithm to find pattern in text.
 // Returns a slice of all starting indices where the pattern is found.
 func RabinKarpSearch(text, pattern string) []int {
+    const base int64 = 31
+    const mod int64 = 1e7 + 7
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2868df and 421a787.

📒 Files selected for processing (1)
  • challenge-23/submissions/nzamulov/solution-template.go (1 hunks)
🔇 Additional comments (3)
challenge-23/submissions/nzamulov/solution-template.go (3)

7-39: LGTM!

The main function correctly sets up test cases and exercises all three pattern matching algorithms. The test cases cover various scenarios including overlapping patterns and repeated characters.


56-82: LGTM! KMP implementation is correct.

The Knuth-Morris-Pratt algorithm is correctly implemented using the pattern+separator+text concatenation approach. The prefix function (pi array) is built correctly, and the index calculation at line 78 (i - 2 * len(pattern)) accurately maps match positions from the concatenated string back to the original text.


87-122: LGTM! Rabin-Karp implementation is correct.

The Rabin-Karp algorithm is correctly implemented with:

  • Proper rolling hash using position-weighted powers
  • Correct hash comparison accounting for window offset (curr_ht == hp * pows[i])
  • String verification to avoid false positives from hash collisions
  • Appropriate handling of negative values in modulo arithmetic (line 116)
  • Edge case validation (empty pattern, pattern longer than text)

The algorithm is sound and handles all edge cases properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant