Skip to content

Add Kaprekar number checker to special_numbers - #12723

Closed
Sean-Randall wants to merge 14 commits into
TheAlgorithms:masterfrom
Sean-Randall:add-kaprekar-check
Closed

Add Kaprekar number checker to special_numbers#12723
Sean-Randall wants to merge 14 commits into
TheAlgorithms:masterfrom
Sean-Randall:add-kaprekar-check

Conversation

@Sean-Randall

Copy link
Copy Markdown

This PR adds a new function is_kaprekar_number(n) under maths/special_numbers/.

The function determines whether a number is a Kaprekar number based on digit-splitting logic, where the square of a number is divided into two parts that sum to the original number. It includes inline doctests to demonstrate usage and ensure correctness.

✔️ This contribution follows all repository contribution guidelines:

  • Type hints included (n: int -> bool)
  • File and function names follow lowercase conventions
  • Clean formatting per PEP8
  • Validated locally using doctest.testmod()

🎯 Educational Value:
This function enhances the repository's coverage of special number classifications and provides a clean, beginner-friendly example of digit-based number theory in Python.

Tested and ready for review. Thank you for maintaining this valuable resource!

@algorithms-keeperalgorithms-keeperBot added tests are failing Do not merge until tests pass and removed tests are failing Do not merge until tests pass labels May 11, 2025
@algorithms-keeperalgorithms-keeperBot added awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass and removed tests are failing Do not merge until tests pass labels May 11, 2025

@mindauglmindaugl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't 10 be a Kaprekar number, since 10^2 = 100, and "100" = "10" + "0" gives 10?

@Sean-Randall

Copy link
Copy Markdown
Author

Shouldn't 10 be a Kaprekar number, since 10^2 = 100, and "100" = "10" + "0" gives 10?

https://cs.uwaterloo.ca/journals/JIS/VOL3/iann2a.html#:~:text=For%20each%20n%20%3E%3D%201%20%2C,)%20when%20N%20%3D%2010n%20.

10 is Disallowed, see above.

@mindaugl

Copy link
Copy Markdown
Contributor

Shouldn't 10 be a Kaprekar number, since 10^2 = 100, and "100" = "10" + "0" gives 10?

https://cs.uwaterloo.ca/journals/JIS/VOL3/iann2a.html#:~:text=For%20each%20n%20%3E%3D%201%20%2C,)%20when%20N%20%3D%2010n%20.

10 is Disallowed, see above.

Thanks for the link. Then, the definition should be clarified in the code function description to be: "Kaprekar numbers: positive numbers n such that n = q+r and n^2 = q*10^m+r, for some m >= 1, q >= 0 and 0 <= r < 10^m, with n != 10^a, a >= 1." (https://oeis.org/A006886)?

@Sean-Randall

Copy link
Copy Markdown
Author

Shouldn't 10 be a Kaprekar number, since 10^2 = 100, and "100" = "10" + "0" gives 10?

https://cs.uwaterloo.ca/journals/JIS/VOL3/iann2a.html#:~:text=For%20each%20n%20%3E%3D%201%20%2C,)%20when%20N%20%3D%2010n%20.
10 is Disallowed, see above.

Thanks for the link. Then, the definition should be clarified in the code function description to be: "Kaprekar numbers: positive numbers n such that n = q+r and n^2 = q*10^m+r, for some m >= 1, q >= 0 and 0 <= r < 10^m, with n != 10^a, a >= 1." (https://oeis.org/A006886)?

Updated the function to align with the strict definition of Kaprekar numbers per OEIS A006886 and Iannucci (1997). Powers of 10 are now explicitly excluded. Let me know if there's anything else to improve!

square = str(n**2)
for i in range(1, len(square)):
left, right = square[:i], square[i:]
if int(right) == 0:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems this check is not needed anymore.

@mindauglmindaugl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just added a comment in code, as the check for int(right) == 0 seems not to be necessary any more after adding explicit check for powers of 10.

@algorithms-keeperalgorithms-keeperBot added the tests are failing Do not merge until tests pass label May 13, 2025
@Sean-Randall

Copy link
Copy Markdown
Author

Just added a comment in code, as the check for int(right) == 0 seems not to be necessary any more after adding explicit check for powers of 10.

Thanks! I removed the int(right) == 0 check as suggested. The new logic excludes powers of 10 directly. Let me know if anything else needs a tweak.

@algorithms-keeperalgorithms-keeperBot added the require descriptive names This PR needs descriptive function and/or variable names label May 13, 2025

@algorithms-keeperalgorithms-keeperBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Click here to look at the relevant links ⬇️

🔗 Relevant Links

Repository:

Python:

Automated review generated by algorithms-keeper. If there's any problem regarding this review, please open an issue about it.

algorithms-keeper commands and options

algorithms-keeper actions can be triggered by commenting on this PR:

  • @algorithms-keeper review to trigger the checks for only added pull request files
  • @algorithms-keeper review-all to trigger the checks for all the pull request files, including the modified files. As we cannot post review comments on lines not part of the diff, this command will post all the messages in one comment.

NOTE: Commands are in beta and so this feature is restricted only to a member or owner of the organization.

import math


def is_kaprekar_number(n: int) -> bool:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please provide descriptive name for the parameter: n

@algorithms-keeperalgorithms-keeperBot removed the require descriptive names This PR needs descriptive function and/or variable names label May 13, 2025
@algorithms-keeperalgorithms-keeperBot removed the tests are failing Do not merge until tests pass label May 13, 2025
@Sean-Randall

Copy link
Copy Markdown
Author

All checks are now passing, including tests, Ruff style checks, and namespace packaging. The implementation follows the strict Kaprekar definition and excludes powers of 10 as required. Everything should be ready for merge. Thanks again for the helpful feedback!

@cclauss

Copy link
Copy Markdown
Member

@priya-sundaram-dev This algorithm is the first Kaprekar PR, and it has pytests instead of doctests (which is OK with me as long as they pass in CI). Is this or one of the four below the best implementation that we should merge?

@priya-sundaram-dev

Copy link
Copy Markdown
Contributor

Thanks for the ping, @cclauss. I read all five and verified the two strongest against OEIS A006886 (canonical Kaprekar numbers ≤ 10000 — both reproduce the sequence exactly, no extras/misses).

One clarification first: #13862 is a different algorithm — it's Kaprekar's constant (the 6174 routine), not the Kaprekar-number predicate. It's not really a duplicate of the other four and could stand on its own merits separately.

That leaves four true is_kaprekar_number candidates. My ranking:

  1. maths: add Kaprekar number implementation #14562 (@Eraol) — my recommendation. Cleanest of the set: pure-integer arithmetic split via %/// (no string parsing), and the right > 0 guard is the mathematically correct way to exclude powers of 10 (10→100 splits to 10+00, rejected because the right part is zero). Concise (~56 lines), doctests cover 1/9/45/55/2223, negatives, and a 1.5 TypeError. ✅ verified against OEIS.
  2. maths/special_numbers: add Kaprekar number #14563 (@Kcstring) — also correct, good doctests, but ~104 lines and raises ValueError on non-positive input where a boolean predicate returning False reads more naturally.
  3. This PR Add Kaprekar number checker to special_numbers #12723 (@Sean-Randall) — logic is correct (✅ verified against OEIS), but it uses math.log10(number).is_integer() to detect powers of 10, which leans on float precision (fine in this range, but the right > 0 integer guard sidesteps it entirely), and it ships pytest tests where the repo prefers doctests.
  4. Kaprekar numbers implementation with doctests #15048 (@VishalNyk) — adds an arbitrary-base parameter; nice generalization but ~173 lines is more surface area than the "one clear educational example" ethos wants.

So: I'd merge #14562 for the checker, and consider #13862 separately as the distinct 6174-routine algorithm. Kudos to everyone — this was a close call between #14562 and #14563.

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

Labels

awaiting reviewsThis PR is ready to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Sean-Randall@mindaugl@cclauss@priya-sundaram-dev