# Programming Praxis – Two Kaprekar Exercises

Published: Wed 23 March 2011

In blog.

Sorry I haven't written in a while. Been rather busy with life recently. I'm still planning on continuing my Tweet Dump series, and I will post that up soon. One of the reasons for the delay is because I'm learning the Colemak keyboard layout has slowed down my typing quite a lot this week.

Anyway, yesterday's Programming Praxis question goes,

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22``` ```For today’s exercise we return to the world of recreational mathematics with two exercises due to the Indian mathematician Dattaraya Ramchandra Kaprekar. First we compute Kaprekar chains: - 1. Choose any four-digit number, with at least two different digits. Leading zeros are permitted. - 2. Arrange the digits into two numbers, one with the digits sorted into ascending order, the other with the digits sorted into descending order. - 3. Subtract the smaller number from the larger number. - 4. Repeat until the number is 6174. At that point, the process will cycle with 7641 − 1467 = 6174. For instance, starting with 2011, the chain is 2110 − 112 = 1998, 9981 − 1899 = 8082, 8820 − 288 = 8532, and 8532 − 2358 = 6174. The second exercise determines if a number is a Kaprekar number, defined as an n-digit number such that, when it is squared, the sum of the first n or n−1 digits and the last n digits is the original number. For instance, 703 is a Kaprekar number because 7032 = 494209 and 494 + 209 = 703. ```

So here is the code I wrote and submitted to the comments section. I will happily admit (like I did in my comment) that my isKaprekar function is a modified version of one I saw in the comments here as it was cleaner than my first version and I wanted to try out the "int(s[:-sz] or 0)" expression)

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29``` ```#!/usr/bin/python3 import itertools def isKaprekar(number): square = str(number ** 2) numlen = len(str(number)) return number == int(square[:-numlen] or 0) + int(square[-numlen:]) def keprekar_chain(number): retlist = [number] if len(set(str(number))) > 2: while retlist[-1] != 6174: pers = [int(''.join(x)) for x in itertools.permutations(str(retlist[-1]))] retlist.append(max(pers) - min(pers)) return retlist else: return [] if __name__ == "__main__": print('Keprekar numbers from 1 to 1000:') print(*[x for x in range(1,1001) if isKaprekar(x)]) print('Longest chain between 1000 and 9999') kep_list = [] for x in range(1000,10000): tlist = keprekar_chain(x) kep_list.append((len(tlist), tlist)) print(sorted(kep_list, key= lambda x: x[0], reverse=True)[0]) ```

That's all for now; more to show up once I can type at normal speeds again.