def factors_as_powers(n): """Yields the factors of n grouped as (factor, power)""" # Avoid the case where n = 1 if n == 1: yield (1, 1) # If n is prime itself, we can early terminate elif Primes.is_prime(n): yield (n, 1) else: primes = iter(Primes(__get_until(n))) while n != 1: try: # If we have a next prime and we can divide, do it prime = next(primes) power = 0 while n % prime == 0: power += 1 n //= prime # If we executed the while loop at least once, return this prime factor if power > 0: yield (prime, power) except StopIteration: # n is now prime itself yield (n, 1) n = 1
def factors(n): """Yields the factors of n""" # Avoid the case where n = 1 if n == 1: yield 1 # If n is prime itself, we can early terminate elif Primes.is_prime(n): yield n # Otherwise, try to divide n by every prime and yield the factors else: primes = iter(Primes(__get_until(n))) # While we can divide it, do it while n != 1: try: # If we have a next prime and we can divide, do it prime = next(primes) while n % prime == 0: n //= prime yield prime except StopIteration: # n is now prime itself yield n n = 1
def count_factors(n): """Counts the factors of n""" # If n equals 1 or is prime itself, it only has one factor # (since 1 is always a factor when n > 1, it is not counted) if n == 1 or Primes.is_prime(n): return 1 else: count = 0 primes = iter(Primes(__get_until(n))) # While we can find more factors while n != 1: try: # If we have a next prime and we can divide, do it prime = next(primes) while n % prime == 0: n //= prime count += 1 except StopIteration: # n is now prime itself count += 1 n = 1 return count
def factors(n): primes = iter(Primes(100000)) while n != 1: prime = next(primes) while n % prime == 0: n //= prime yield prime
def search(): max_goal = 8 max_primes = 0 for prime in Primes(1000000): for fam in families(prime): prime_count = 0 for child in fam(): if Primes.is_prime(child): prime_count += 1 if prime_count > max_primes: max_primes = prime_count print('New max of {} for prime {}'.format(prime_count, prime)) for child in fam(): if Primes.is_prime(child): print(child, end=' ') print() if prime_count == max_goal: return
def check_primes(prime_count=5, primes=[], last_largest_prime=0): if len(primes ) >= 2: # perform checks as soon as we can for early termination # Concatenate all possible permutations and ensure they're primes for p in permutations(primes, 2): if not Primes.is_prime(int(str(p[0]) + str(p[1]))): return # We can avoid some combinations... (previously checked ones) if len(primes) == prime_count: print('Succeed for {}, which adds to {}'.format( primes, sum(primes))) if len(primes) < prime_count: # carry on getting more primes for prime in Primes(max_prime): if prime <= last_largest_prime: continue # do not use a lower prime (already used) # Clone list, append prime, and dive into the next recursion level next_primes = primes[:] next_primes.append(prime) check_primes(prime_count, next_primes, prime)
def work(): prime_count = 0 number_count = 1 # skip 1, so we never get the ratio 0/1 for x in range(1, 20000): for n in get_diagonals(x): number_count += 1 if Primes.is_prime(n): prime_count += 1 ratio = prime_count / number_count if x % 100 == 0: print('{:.2%}'.format(ratio)) if ratio < 0.1: # less than 10% print(spiral_length(x)) return
from lw.primes import Primes def problem_definition(): return '''The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. Find the sum of all the primes below two million.''' print(sum(Primes(2000000)))
but there is one other 4-digit increasing sequence. What 12-digit number do you form by concatenating the three terms in this sequence?''' def are_permutation(a, b): a = tuple(str(a)) b = tuple(str(b)) for permutation in permutations(a): if permutation == b: return True return False for i in range(1000, 10000): if not Primes.is_prime(i): continue for j in range(1000, 10000): next2 = i + j + j if next2 > 9999: # must be 4-digit break if not Primes.is_prime(next2): continue next1 = i + j if not Primes.is_prime(next1): continue if not are_permutation(i, next2): continue
done = False maximum = 1000000 largestprime = 0 largestcount = 0 for _skip in range(maximum): if done: break firstprime = True primesum = 0 countsum = 0 skip = _skip for prime in Primes(maximum): # Skip the previously checked prime sum sequences if skip > 0: skip -= 1 continue # If the first prime is already larger than the difference # between the latest largest sum and the maximum to check, # there is no point on carrying on checking, because any # sum will be larger with less numbers being summed if firstprime: firstprime = False if prime > maximum - largestprime: done = True break
def specific_solution(): for prime1 in Primes(max_prime): s_prime1 = str(prime1) for prime2 in Primes(max_prime): # Avoid checking the same primes if prime2 <= prime1: continue s_prime2 = str(prime2) # Check if concatenating is prime if not Primes.is_prime(int(s_prime1 + s_prime2)): continue if not Primes.is_prime(int(s_prime2 + s_prime1)): continue # print('Checking level 2: {}, {}'.format(prime1, prime2)) for prime3 in Primes(max_prime): # Avoid checking the same primes if prime3 <= prime2: continue s_prime3 = str(prime3) # Check if concatenating is prime if not Primes.is_prime(int(s_prime1 + s_prime3)): continue if not Primes.is_prime(int(s_prime3 + s_prime1)): continue if not Primes.is_prime(int(s_prime2 + s_prime3)): continue if not Primes.is_prime(int(s_prime3 + s_prime2)): continue # print('Checking level 3: {}, {}, {}'.format(prime1, prime2, prime3)) for prime4 in Primes(max_prime): # Avoid checking the same primes if prime4 <= prime3: continue s_prime4 = str(prime4) # Check if concatenating is prime if not Primes.is_prime(int(s_prime1 + s_prime4)): continue if not Primes.is_prime(int(s_prime4 + s_prime1)): continue if not Primes.is_prime(int(s_prime2 + s_prime4)): continue if not Primes.is_prime(int(s_prime4 + s_prime2)): continue if not Primes.is_prime(int(s_prime3 + s_prime4)): continue if not Primes.is_prime(int(s_prime4 + s_prime3)): continue # print('Checking level 4: {}, {}, {}, {}'.format(prime1, prime2, prime3, prime4)) for prime5 in Primes(max_prime): # Avoid checking the same primes if prime5 <= prime4: continue s_prime5 = str(prime5) # Check if concatenating is prime if not Primes.is_prime(int(s_prime1 + s_prime5)): continue if not Primes.is_prime(int(s_prime5 + s_prime1)): continue if not Primes.is_prime(int(s_prime2 + s_prime5)): continue if not Primes.is_prime(int(s_prime5 + s_prime2)): continue if not Primes.is_prime(int(s_prime3 + s_prime5)): continue if not Primes.is_prime(int(s_prime5 + s_prime3)): continue if not Primes.is_prime(int(s_prime4 + s_prime5)): continue if not Primes.is_prime(int(s_prime5 + s_prime4)): continue print('We did it! {} + {} + {} + {} + {} = {}'.format( prime1, prime2, prime3, prime4, prime5, prime1 + prime2 + prime3 + prime4 + prime5)) return
from lw.primes import Primes def problem_definition(): return '''The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property. Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.''' max_prime = 10000 print('Caching some primes...') Primes(max_prime) print('Doing work (please be patient)...') # This general solution works for n def check_primes(prime_count=5, primes=[], last_largest_prime=0): if len(primes ) >= 2: # perform checks as soon as we can for early termination # Concatenate all possible permutations and ensure they're primes for p in permutations(primes, 2): if not Primes.is_prime(int(str(p[0]) + str(p[1]))): return # We can avoid some combinations... (previously checked ones) if len(primes) == prime_count: print('Succeed for {}, which adds to {}'.format(