-
Notifications
You must be signed in to change notification settings - Fork 0
/
cycle_integer.py
65 lines (50 loc) · 1.69 KB
/
cycle_integer.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
"""
The problem:
Given an integer n in base b, two new values can be created by taking the digits
of n in ascending and descending order. The difference between these two values
is used to produce the next n. Find the length of the loop when the values of n
repeat in a cycle.
The solution:
Because any value n will create the same two values when its digits are organized,
once a value n appears again, a cycle is inevitable. The number of values between the
first n and the first time n reappears (including one of the n's) gives the length of
the loop.
Create a list that contains all n values and check if it's already in the list when
adding a new n value.
"""
def solution(n, b):
id_values = []
# List of id values that have gone through the algorithm.
# If the next id is already in the list, we have found
# our loop starting point
def chores(n, b):
# define our algorithm
id_values.append(n) # add n to id list
k = len(n) # length of id in base b
# id values turned to string so digits can be sorted
pre_y = sorted(n)
pre_x = pre_y[::-1]
# x and y turned back to ints, but of base b
x = int("".join(pre_x), b)
y = int("".join(pre_y), b)
# difference "z" is calculated in base 10
z = x - y
# z converted to base b
i = k-1
z_b =[]
while i >=0:
exp = b**i
digit = z//exp
z_b.append(str(digit))
z = z - (digit*exp)
i -= 1
z = "".join(z_b)
z = str(z).zfill(k) #leading zeroes added back to z if necessary
if z in id_values:
# if z already in id list, find lenth of loop
loop_size = (len(id_values) - id_values.index(z))
return loop_size
else:
# recursive call for next id
return chores(z,b)
return chores(n,b)