-
Notifications
You must be signed in to change notification settings - Fork 0
/
kaprekar.py
executable file
·71 lines (54 loc) · 2.07 KB
/
kaprekar.py
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env python3
"""
Demonstrates convergence to the Kaprekar's constant 6174
"""
__author__ = "Daniele Raffo"
__version__ = "0.1"
__date__ = "30/6/2021"
import argparse
import sys
import random
def parse_command_line():
"""Parse command line arguments"""
parser = argparse.ArgumentParser(description = __doc__)
group = parser.add_mutually_exclusive_group(required = True)
group.add_argument('-n', dest = 'nstart', help = 'A positive 4-digit number to start the routine (digits must not be all the same; leading zeros are allowed)')
group.add_argument('-r', '--random', action = 'store_true', help = 'Runs the Kaprekar\'s routine with a random 4-digit number')
return parser
def num_to_digitlist(n):
"""Return a List containing the digits of a 4-digit number"""
s = str(n).zfill(4)
return [s[0], s[1], s[2], s[3]]
def digitlist_to_num(l):
"""Return a number obtained by concatenating the 4 digits stored in a List"""
s = [str(i) for i in l]
return int("".join(s))
def run_kaprekar_routine(n):
"""Run a step of the Kaprekar's routine and return the next number"""
digits = num_to_digitlist(n)
nmin = digitlist_to_num(sorted(digits))
nmax = digitlist_to_num(sorted(digits, reverse=True))
ndiff = nmax - nmin
print("{} - {:04d} = {:04d}".format(nmax, nmin, ndiff))
return ndiff
if __name__ == '__main__':
args = parse_command_line().parse_args()
if args.nstart:
number = int(args.nstart)
if number < 1 or number > 9999:
print('Error: argument must be a positive 4-digit number')
sys.exit()
digits = num_to_digitlist(number)
if digits.count(digits[0]) == len(digits):
print('Error: digits must not be all the same')
sys.exit()
else:
while True:
number = random.randrange(1, 9998)
digits = num_to_digitlist(number)
if digits.count(digits[0]) != len(digits):
break
while True:
number = run_kaprekar_routine(number)
if number == 6174:
break