|
1
|
|
|
__author__ = 'KenMercusLai' |
|
2
|
|
|
|
|
3
|
|
|
|
|
4
|
|
|
def find_repeats(decimal_string): |
|
5
|
|
|
for i in range(0, (len(decimal_string)) // 3): |
|
6
|
|
|
first, second, third = ( |
|
7
|
|
|
decimal_string[-i * 3 - 3 : -i * 2 - 2], |
|
8
|
|
|
decimal_string[-i * 2 - 2 : -1 - i], |
|
9
|
|
|
decimal_string[-1 - i :], |
|
10
|
|
|
) |
|
11
|
|
|
if first and first == second == third: |
|
12
|
|
|
return ( |
|
13
|
|
|
len(decimal_string) - 1 - i * 3 - 2, |
|
14
|
|
|
len(decimal_string) - 1 - i * 2 - 1, |
|
15
|
|
|
) |
|
16
|
|
|
return None, None |
|
17
|
|
|
|
|
18
|
|
|
|
|
19
|
|
|
def get_next_decimal(numerator, denominator): |
|
20
|
|
|
while 1: |
|
21
|
|
|
decimals = str(numerator * 10 // denominator) |
|
22
|
|
|
numerator = numerator * 10 % denominator |
|
23
|
|
|
yield decimals |
|
24
|
|
|
|
|
25
|
|
|
|
|
26
|
|
|
def convert(numerator, denominator): |
|
27
|
|
|
decimal_generator = get_next_decimal(numerator % denominator, denominator) |
|
28
|
|
|
decimal_string = '' |
|
29
|
|
|
for i in range(10000): |
|
30
|
|
|
decimal_string += next(decimal_generator) |
|
31
|
|
|
if decimal_string[-3:] == '000': |
|
32
|
|
|
return '%d.%s' % (numerator / denominator, decimal_string[:-3]) |
|
33
|
|
|
if len(decimal_string) < 3: |
|
34
|
|
|
continue |
|
35
|
|
|
start_pos, end_pos = find_repeats(decimal_string) |
|
36
|
|
|
if start_pos is not None: |
|
37
|
|
|
return '%d.%s(%s)' % ( |
|
38
|
|
|
numerator / denominator, |
|
39
|
|
|
decimal_string[:start_pos], |
|
40
|
|
|
decimal_string[start_pos:end_pos], |
|
41
|
|
|
) |
|
42
|
|
|
|
|
43
|
|
|
|
|
44
|
|
|
if __name__ == '__main__': # pragma: no cover |
|
45
|
|
|
# These "asserts" using only for self-checking and not necessary for |
|
46
|
|
|
# auto-testing |
|
47
|
|
|
assert convert(1, 3) == "0.(3)", "1/3 Classic" |
|
48
|
|
|
assert convert(5, 3) == "1.(6)", "5/3 The same, but bigger" |
|
49
|
|
|
assert convert(3, 8) == "0.375", "3/8 without repeating part" |
|
50
|
|
|
assert convert(7, 11) == "0.(63)", "7/11 prime/prime" |
|
51
|
|
|
assert convert(29, 12) == "2.41(6)", "29/12 not and repeating part" |
|
52
|
|
|
assert convert(11, 7) == "1.(571428)", "11/7 six digits" |
|
53
|
|
|
assert convert(0, 117) == "0.", "Zero" |
|
54
|
|
|
|