Passed
Push — master ( e560e6...6cdffb )
by Ken M.
02:07 queued 58s
created

repeating_decimals.convert()   A

Complexity

Conditions 5

Size

Total Lines 15
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 15
nop 2
dl 0
loc 15
rs 9.1832
c 0
b 0
f 0
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