def p50(n=1000000): '''Solution to problem 50 This solution can be executed within a second ''' # first generate a set of primes below n for testing primality in O(1) primes = set([p for p in sieve(n)]) # create a list of consective primes that add up just below n cps, s = [], 0 for p in sieve(n): if s <= n: s += p cps.append(p) else: break # let's search the answer! ans, b, e, found = 0, 0, 0, False for l in xrange(len(cps), 0, -1): for i in xrange(0, len(cps)-l+1): s = sum(cps[i:i+l]) # the first sum found is actually the answer! # no needs to continue searching anymore! if s in primes: ans, b, e, found = s, i, i+l, True break if found: break print ans, 'with', len(cps[b:e]), 'terms'
def p21(limit=10000): '''Solution to problem 21 ''' def d(n): '''d(n) Calculate the sum of proper divisors of n. ''' s = 1 facs = euler11_20.factorize(n) for k in facs: s *= (k**(facs[k]+1) - 1)/(k-1) return s - n amicables = [True for x in xrange(limit)] # prime numbers cannot be amicable numbers # so we eliminate checking those numbers for x in euler1_10.sieve(limit): amicables[x] = False # cross out non-amicable numbers for x in xrange(220, limit): if amicables[x]: y = d(x) amicables[x] = False if (d(y) != x or x == y) else True # calculate the sum of amicable pairs and output s = 0 for i in xrange(220, limit): if amicables[i]: s += i print s
def p47(): '''Solution to problem 47 This brute-force solution takes about 17 seconds to run on my laptop. Some thoughts for improvement: 1. Maybe you don't need to factorize to test distinct number of factors 2. There are some redundant computations, like testing the same number more than once ''' # store a list of primes below 1000000 primes = set([p for p in sieve(1000000)]) b = 2*3*5*7 # storing the first 4 distinct prime factors number e = b+3 # storing the next number to be computed # i, wl = 2*3*5*7, 0 # while True: # if not (i+3) in primes and len(factorize(i+3)) == 4: # if not (i+2) in primes and len(factorize(i+2)) == 4: # if not (i+1) in primes and len(factorize(i+1)) == 4: # if not i in primes and len(factorize(i)) == 4: # # anwer found! # break # else: # i += 1 # else: # i += 2 # else: # i += 3 # else: # i += 4 while b != e: if not e in primes and len(factorize(e)) == 4: e -= 1 if not e in primes and len(factorize(e)) == 4: e -= 1 if not e in primes and len(factorize(e)) == 4: e -= 1 if not e in primes and len(factorize(e)) == 4: # anwer found! break else: b, e = e+1, e+4 else: b, e = e+1, e+3 else: b, e = e+1, e+2 else: b, e = e+1, e+4 print b
def p35(limit=1000000): '''Solution to problem 35 ''' # Building a dictionary of primes below 1 million primes = {} for p in sieve(1000000): primes[p] = False # Initialize to NOT a circular prime n_of_cprimes = 0 # number of circular primes for p in primes.keys(): n = str(p) l = len(n) # number of iterations to rotate the string while l != 0: n = n[1:] + n[0] # string rotation if int(n) not in primes: break l -= 1 if l == 0: n_of_cprimes += 1 primes[p] = True print n_of_cprimes
def p37(): '''Solution to problem 37 ''' def is_truncatable_prime(p=0, d=None): "Return True if p is a truncatable prime from left to right, otherwise False" rel, p_from_right, p_from_left = True, str(p), str(p) l = len(p_from_left) while l > 0: if int(p_from_left) in d and int(p_from_right) in d: p_from_left = p_from_left[1:] p_from_right = p_from_right[:-1] l -= 1 else: rel = False break return rel s, primes = 0, set([p for p in sieve(800000)]) for p in xrange(23, 800000, 2): if is_truncatable_prime(p, primes): s += p print s