Skip to content

feat: add repunit theorem helpers#1892

Open
nickzerjeski wants to merge 4 commits intoTheAlgorithms:masterfrom
nickzerjeski:feat-repunit-theorem-1866
Open

feat: add repunit theorem helpers#1892
nickzerjeski wants to merge 4 commits intoTheAlgorithms:masterfrom
nickzerjeski:feat-repunit-theorem-1866

Conversation

@nickzerjeski
Copy link
Copy Markdown

Describe your change:

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

Added repunit theorem utilities in Maths/RepunitTheorem.js:

  • multiplicative order of 10 modulo a prime
  • theorem-based repunit divisibility check
  • repunit modulo computation without constructing huge integers

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 JavaScript files are placed inside an existing directory.
  • All filenames should use the UpperCamelCase (PascalCase) style. There should be no spaces in filenames.
  • All new algorithms have a URL in their comments that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the commit message contains Fixes: #{$ISSUE_NO}.

Tests

  • npm test -- RepunitTheorem

@nickzerjeski nickzerjeski requested a review from appgurueu as a code owner April 13, 2026 09:00
Copilot AI review requested due to automatic review settings April 13, 2026 09:00
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds repunit theorem–related utilities to the Maths module, enabling theorem-based divisibility checks and modular computations for repunits without constructing large integers.

Changes:

  • Introduces multiplicativeOrder10, repunitMod, and isRepunitDivisibleByPrime in Maths/RepunitTheorem.js.
  • Adds Jest tests covering example orders, theorem-based divisibility cases, and repunit modulo computations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
Maths/RepunitTheorem.js Implements BigInt-based helpers for multiplicative order, repunit modulo, and a theorem-based divisibility check.
Maths/test/RepunitTheorem.test.js Adds unit tests for the new repunit theorem helpers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +65 to +75
const isRepunitDivisibleByPrime = (length, prime) => {
if (!Number.isInteger(length) || length < 1) {
throw new RangeError('length must be a positive integer')
}

const p = BigInt(prime)
if (p === 2n || p === 5n) return false
if (gcd(10n, p) !== 1n) return false

const order = multiplicativeOrder10(p)
return BigInt(length) % order === 0n
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

The stated divisibility criterion and current implementation fail for p = 3. Since gcd(9,3) != 1, “ord_p(10) divides n” is not equivalent to 3 | R_n (e.g., length=1 would incorrectly return true because ord_3(10)=1). Handle p===3n explicitly (R_n mod 3 == n mod 3) and/or update the theorem condition to require p not dividing 9 (i.e., exclude p=3).

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +9
/**
* Repunit theorem helpers.
*
* A repunit of length n is:
* R_n = (10^n - 1) / 9
*
* For a prime p (p != 2, 5), p divides R_n iff ord_p(10) divides n.
* Reference: https://en.wikipedia.org/wiki/Repunit
*/
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

The file header comment says the theorem holds for primes p != 2,5, but it also needs p != 3 (equivalently gcd(p,9)=1). As written, it documents an incorrect condition and matches the buggy behavior for p=3.

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +46
// For prime p, ord_p(10) divides p-1.
const upper = p - 1n
for (let k = 1n; k <= upper; k++) {
if (upper % k === 0n && modPow(10n, k, p) === 1n) {
return k
}
}
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

multiplicativeOrder10 currently checks every k from 1..p-1 and runs modPow for each divisor check, which is O(p log p) and will be extremely slow for larger primes. Consider iterating only divisors of (p-1) (e.g., enumerate divisors up to sqrt(p-1) or factor p-1 and test candidate orders by reducing factors) to keep runtime practical.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +27
it('checks repunit divisibility using the theorem', () => {
// 111111 is divisible by 3, 7, 11, 13, 37
expect(isRepunitDivisibleByPrime(6, 3n)).toBe(true)
expect(isRepunitDivisibleByPrime(6, 7n)).toBe(true)
expect(isRepunitDivisibleByPrime(6, 11n)).toBe(true)
expect(isRepunitDivisibleByPrime(6, 13n)).toBe(true)
expect(isRepunitDivisibleByPrime(6, 37n)).toBe(true)
})

it('returns false when divisibility condition does not hold', () => {
expect(isRepunitDivisibleByPrime(6, 19n)).toBe(false)
expect(isRepunitDivisibleByPrime(9, 2n)).toBe(false)
expect(isRepunitDivisibleByPrime(9, 5n)).toBe(false)
})
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

Add an explicit test case for p=3 (e.g., length=1 should be false and length=3 should be true). The current tests only cover a length (6) where 3 happens to divide the repunit, so they won’t catch the p=3 edge case where the theorem-based check is incorrect.

Copilot uses AI. Check for mistakes.
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 13, 2026

Codecov Report

❌ Patch coverage is 96.20253% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.95%. Comparing base (5c39e87) to head (45aa3f4).

Files with missing lines Patch % Lines
Maths/RepunitTheorem.js 96.20% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1892      +/-   ##
==========================================
+ Coverage   85.91%   85.95%   +0.04%     
==========================================
  Files         379      380       +1     
  Lines       19778    19857      +79     
  Branches     3016     3043      +27     
==========================================
+ Hits        16993    17069      +76     
- Misses       2785     2788       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

3 participants