Kaprekar’s constant

Here is the problem:

The number 6174 is known as Kaprekar’s constant, after the mathematician who discovered an associated property:

for all fourdigit numbers with at least two distinct digits, repeatedly applying a simple procedure eventually results in this value.

The procedure is as follows:

For a given input x, create two new numbers that consist of the digits in x in ascending and descending order.Subtract the smaller number from the larger number.

For example, this algorithm terminates in three steps when starting from 1234:

  • 4321 – 1234 = 3087
  • 8730 – 0378 = 8352
  • 8532 – 2358 = 6174

Write a function that returns how many steps this will take for a given input N.

Solution

First, lets define a function:

def Kaprekar(n):
    '''
    take a number n and do a Kaprekar process

    inputs:
        n: an interger number to be processed

    return: the number of iterations
    '''

next, we need to check that the number is 4 digits long.

    # is the number 4 digits
    if n >= 1000 and n <= 9999:
        pass
        #print('acceptable number')
    else:
        return 'number needs to be 4 digits'

next, check that there are at least 2 distinct digits.

We use the collections module to assist.

    import collections    

    # check for two distinct digits
    numAsList = str(n)
    counter=collections.Counter(numAsList)
    if counter.most_common(1)[0][1] > 2:
        print('the number', counter.most_common(1)[0][0], 'occurs too frequently')
        return 'needs more distinct numbers'

Finally, lets do some loops with the actual process.

    for i in range(10):
        ascending = sorted(numAsList)
        ascending = int(''.join(ascending))
        descending = sorted(numAsList, reverse=True)
        descending = int(''.join(descending))

        #print('the new number:',descending-ascending)
        processedNumber = descending - ascending

        # check if processed number = contant
        if processedNumber == contant:
            return f'result found after {i+1} iterations'
        else:
            numAsList = str(processedNumber)

Full code all in one go:

import collections


startNum = int(input('enter a 4 digit number: '))
contant = 6174

def Kaprekar(n):
    '''
    take a number n and do a Kaprekar process

    inputs:
        n: an interger number to be processed

    return: the number of iterations
    '''

    # is the number 4 digits
    if n >= 1000 and n <= 9999:
        pass
        #print('acceptable number')
    else:
        return 'number needs to be 4 digits'
    
    # check for two distinct digits
    numAsList = str(n)
    counter=collections.Counter(numAsList)
    if counter.most_common(1)[0][1] > 2:
        print('the number', counter.most_common(1)[0][0], 'occurs too frequently')
        return 'needs more distinct numbers'

    
    # now do the processing

    # lets do 10 loops
    for i in range(10):
        ascending = sorted(numAsList)
        ascending = int(''.join(ascending))
        descending = sorted(numAsList, reverse=True)
        descending = int(''.join(descending))

        #print('the new number:',descending-ascending)
        processedNumber = descending - ascending

        # check if processed number = contant
        if processedNumber == contant:
            return f'result found after {i+1} iterations'
        else:
            numAsList = str(processedNumber)
    


    return 'should never get here'
    


result = Kaprekar(startNum)

print(result)

Statistics:

Here are the results when the above is looped over all possible numbers.

  • number of results: 8667
  • the least iterations: 1
  • the most iterations: 7
  • the average iterations: 4.667
  • the stdev iterations: 1.804

Here is a histogram of the results:

source: dlefcoe python code

Thank you for reading.

Leave a Reply

Your email address will not be published.