def minG(m): p = phi(m) mp = factor(p) checkLst = [p // i for i in mp] i = 2 while 1: if all((i**n - 1) % m != 0 for n in checkLst): return i i += 1
def gs(m, num=100): '''return list of m's primary roots below num''' p = phi(m) mp = factor(p) checkLst = [p // i for i in mp] return [ i for i in range(2, num) if all((i**n - 1) % m != 0 for n in checkLst) ]
def solC(): counter = 0 phi = [-1] * (n) psqrd = [-1] * (n) phi[2] = 1 psqrda = [] for i in primes: psqrda.append([]) for p in primes: pk = p k = 1 while pk < n: phi[pk]=int(pk*(1-1/p)) psqrd[pk]=p #psqrda[primes.index(p)].append(pk) k+=1 pk*=p counter+=1 print(counter/n*100,"% done") for i in range(1,n): if psqrd[i] == -1: continue for coprime in range(i+1,n): if phi[coprime] == -1 or psqrd[coprime] == -1: continue if psqrd[i] == psqrd[coprime]: continue if i * coprime >= n: break if phi[i] != -1 and phi[i*coprime] == -1 and coprime % i != 0: phi[i*coprime] = phi[i]*phi[coprime] counter+=1 print(counter/n*100,"% done") # for i in psqrda[0]: # while psqrd print(counter/n*100,"% done") missed = 0 for i in range(2,n): if phi[i] == -1: phi[i] = euler.phi(i,primes) missed+=1 counter+=1 if i%10000 == 0: print(counter/n*100,"% done") print("Amount missed",missed) return phi
def solveHigh(self, a, n, b, m): ''' ax^n -- b (mod m) ind_mp is a dict of m's {n: indg n}''' ind_mp = ind(m, minG(m)) tmp = ind_mp[b] - ind_mp[a] if tmp < 0: tmp += m sol = self.solveLinear(n, tmp, phi(m)) re_mp = {j: i for i, j in ind_mp.items()} sols = [re_mp[i] for i in sol[0]] print('{}x^{}--{}(mod {}), solution: {} mod {}'.format( a, n, b, m, sols, m)) return sols, m
def slow_solve(): min_ratio = 999999999 for x in primes[200:LOWER_BOUND]: for y in primes: n = x*y if n > UPPER_BOUND: break p = phi(n) if is_permutation(n, p): ratio = n/p if ratio < min_ratio: min_ratio = ratio print("(x,y)=({},{}), n={}, phi(n)={}, ratio={}".format(x,y,n,p, n/p))
def fast_solve(): # find out where to start sqrt_index = 0 for i in range(len(primes)): if primes[i] > SQRT_UPPER: sqrt_index = i break x_index = sqrt_index while x_index > 0: print("Trying with x at index {} with value {}".format(x_index, primes[x_index])) y_index = sqrt_index while y_index < len(primes): n = primes[x_index] * primes[y_index] if n > UPPER_BOUND: break p = phi(n) if is_permutation(n, p): print("n={}, phi(n)={}, ratio={}".format(n,p, n/p)) return y_index += 1 x_index -= 1
def n_over_phi(n): return n / phi(n)
if sorted(str(n1)) == sorted(str(n2)): return True else: return False n_max = 10**7 search_range = 1000 search_start = floor(sqrt(n_max)) - search_range search_end = floor(sqrt(n_max)) + search_range prime_list = [] for prime in prime_sieve(search_end): if prime > search_start: prime_list.append(prime) candidate = 1 smallest_ratio = 10 for i in range(len(prime_list)): for j in range(i, len(prime_list)): n = prime_list[i]*prime_list[j] if n >= 10**7: break phi_n = phi(n) ratio = n/phi_n if is_permutation(n, phi(n)) and ratio < smallest_ratio: candidate = n smallest_ratio = ratio print(candidate, smallest_ratio) print("time elapsed:", time() - T)
# https://projecteuler.net/problem=69 from euler import phi, prime_sieve from time import time T = time() # brute force: max_value = 0 max_value_num = 2 for num in range(2, 10**6+1): n_div_phi = num/phi(num) if n_div_phi > max_value: max_value = n_div_phi max_value_num = num print(max_value_num) print("time elapsed:", time() - T) """ Pen and paper method: Notice that n/phi(n) = 1/((1-1/p1)*(1-1/p2)...) Hence n/phi(n) is maximal when ((1-1/p1)*(1-1/p2)...) is minimal This happens using the smallest primes, so we simply multiply the smallest primes together and make sure we stay under 10^6 """ T = time() s = 1 for i in prime_sieve(100): s *= i if s > 10**6: print(s // i)
# Euler 72 # Consider the fraction, n/d, where n and d are positive integers. If n<d and # HCF(n,d)=1, it is called a reduced proper fraction. # # If we list the set of reduced proper fractions for d ≤ 8 in ascending order # of size, we get: # # 1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8 # # It can be seen that there are 21 elements in this set. # # How many elements would be contained in the set of reduced proper fractions for # d ≤ 1,000,000? # [Benoit] Looking at the fractions with 8 as denominator above, we only see 1/8, 3/8, 5/8 and 7/8. # Others such as 2/8 are not present, because that's the same as 1/4. The numerators 1,3,5,7 persist # because no smaller number shares a factor with them (thus they cannot be reduced). # 1,3,5,7 are CO-PRIME with 8. How we we count those? That's the phi function! from euler import phi num = sum([phi(i) for i in range(2,1_000_001)]) print(num)
def farey_length(n): res = 1 for m in range(1, n+1): res += phi(m) return res-2 # discount the endpoints due to the exercise