from copy import deepcopy from itertools import islice def primes(n): """ Nice way to calculate primes. Should be fast. """ l = range(2, n + 1) _l = [] while True: p = l[0] if p * p > n: return _l + l l = [i for i in l if i % p != 0] _l.append(p) def calculate_decimal_places(numerator, denominator): numerator = (numerator - (numerator / denominator) * denominator) * 10 digits = [] while True: digit = numerator / denominator numerator = (numerator - digit * denominator) * 10 digits.append(digit) if digits[-3:] == [0, 0, 0]: raise StopIteration yield digit def has_cycle(decimal_places, n): d = decimal_places return list(islice(d, 0, n)) == list(islice(d, 0, n)) and \ list(islice(d, 0, n)) == list(islice(d, 0, n)) def f_025_1(): """ Second try. I realized that only primes must be checked. Therefore, my brute force approach worked. """ l = [] for d in primes(1000): for i in range(5, 10000): decimal_places = calculate_decimal_places(1, d) if has_cycle(decimal_places, i): l.append((i, d)) break print(max(l)) def calculate_cycle(numerator, denominator): numerator = (numerator - (numerator / denominator) * denominator) * 10 remainders = set([]) while True: digit = numerator / denominator remainder = (numerator - digit * denominator) if remainder in remainders: raise StopIteration remainders.add(remainder) numerator = remainder * 10 yield digit def f_025_2(): """ Understood trick with remembering remainder... """ s = [(len(list(calculate_cycle(1, d))), d) for d in range(1, 1001)] print(max(s)) def f_025_3(): """ Only testing primes... """ s = [(len(list(calculate_cycle(1, d))), d) for d in primes(10000)] print(max(s)) f_025_3() #print([(find_cycle_count(calculate_decimal_places(1, d)), d) # for d in range(1, 100)]) #print(find_cycle_count(calculate_decimal_places(22, 7))) #l = [] #for d in range(1, 1000): # for i in range(5, 1000): # decimal_places = calculate_decimal_places(1, d) # if has_cycle_one_off(decimal_places, i): # l.append((i, d)) # break # decimal_places = calculate_decimal_places(1, d) # if has_cycle(decimal_places, i): # l.append((i, d)) # break #def find_cycle_count(decimal_places): # cycles = [] # for digit in decimal_places: # new_cycles = [] # for cycle in cycles: # digits, length = cycle # if digits[0] == digit: # if len(digits[1:]) == 0: # return length # new_cycles.append((digits[1:], length)) # new_cycles.append((digits + [digit], length + 1)) # new_cycles.append(([digit], 1)) # cycles = new_cycles