Skip to Main Content
Blog

Print all Kaprekar Numbers in Python

Print all Kaprekar Numbers in Python

Enter lower bound: 1
Enter upper bound: 9999
9, 45, 55, 99, 297, 703, 999, 2223, 2728, 4879, 4950, 5050, 5292, 7272, 7777, 9999,
import math


# Checks if a number is a Kaprekar number or not.
def is_kaprekar(num: int) -> bool:
    """
    Checks if a number is a Kaprekar number or not.

    A Kaprekar number is a number whose square when divided into two parts
    and such parts are added, the result is the original number.
    """
    radix = 10

    sqr = num * num
    len_num = number_length(num, radix)
    valid = False
    for i in range(1, len_num + 1):
        div = int(math.pow(radix, i))
        if div != num:
            sum_parts = sqr // div + sqr % div
            if sum_parts == num:
                valid = True
                break
    return valid


# Finds the length of a number in a given radix.
def number_length(num: int, radix: int) -> int:
    """
    Finds the length of a number in a given radix.

    If the number is 0, its length is 1. Otherwise, the length is calculated
    using the logarithm of the number with the given radix.
    """
    if num == 0:
        return 1

    num = abs(num)
    if radix == 10:
        len_num = int(math.floor(math.log10(num))) + 1 if num != 0 else 1
    else:
        len_num = (
            int(math.floor(math.log(num) / math.log(radix))) + 1 if num != 0 else 1
        )

    return len_num


def main():
    # Get the lower and upper limits from the user
    lower_limit = int(input("Enter lower limit: "))
    upper_limit = int(input("Enter upper limit: "))

    # Find and print all Kaprekar numbers within the given range
    kaprekar_numbers = [
        i for i in range(lower_limit, upper_limit + 1) if is_kaprekar(i)
    ]
    print(*kaprekar_numbers, sep=", ")


if __name__ == "__main__":
    main()