def firstnotdiv(n, primelist = None): """Finds the set of primes not divisible by the first n primes, with the least quantity of primes, that is the distinct prime factorization of at least one primitive abundant number""" if primelist == None: #... then we have to include a parallel prime sieve, like with primes2.pf p = 3 #The first odd prime plist = [2] #The only even prime if n == 0: #If they want 6 as the result . . . res = [2] #Then we have to include two in the result. We wouldn't otherwise. num = 2 #Why not give the numerator, denomerator, quotient and remainder straight away? den = 1 q = 2 r = 0 else: #Otherwise, . . . res = [] #We start with an empty result list. num = 1 #We give 1's as the num and den, as we will be using *= extensively. den = 1 q = 1 #We give bogus quotient and result, that will not pass the test the first time r = 0 while len(plist)<n: #Build up the first n primes, before we worry about the numerator and denominator. low = primes2.low(primes2.lim(p)+1, plist) #Standard parallel prime sieve. if primes2.divtest(low, p): plist.append(p) p += 2 else: p += 2 while not test(q,r): #While we have not found enough primes . . . (stops at the first sufficient prime) low = primes2.low(primes2.lim(p)+1, plist) #Standard parallel prime sieve if primes2.divtest(low, p): plist.append(p) res.append(p) #if it is prime, add it to the list num *= p #Change the numerator den *= (p - 1) #Change the denominator q, r = num/den, num%den #Change quotient and remainder. For justification, see earlier functions. p += 2 else: p += 2 return res #We do want a result, right? else: c = primelist[n:] #Cut the first n off i = 0 #Initiate; index at 0, num and den at 1 (to be multiplied), q and r non-passing bogus, empty result num = 1 den = 1 q = 1 r = 0 res = [] #End initiation while not test(q,r): #As long as we do not have enough primes, . . . res.append(c[i]) #We need at least one more. num *= c[i] #Check if it was enough; multiply to num and den, and reset q and r. den *= (c[i] - 1) q, r = num/den, num%den i += 1 #Index must increase return res #We are done.
def firstsquarefree(n, primelist = None): """Returns the first squarefree prim. ab. num. not divisible by the first n primes.""" if primelist == None: #...then another parallel prime sieve p = 3 #See firstnotdiv for details on the prime sieve initiation plist = [2] if n == 0: #We save time by only checking odds for primality; 2 must be a special case. res = [(2, 1)] #Just give the true values for initiation here. num = 3 den = 2 q = 1 else: #Initiate empty result, multiplicative identity for num and den, and bogus, not-passing q res = [] num = 1 den = 1 q = 1 while len(plist)<n: #Standard prime sieve. Build up the list of primes to the necessary length. low = primes2.low(primes2.lim(p)+1, plist) if primes2.divtest(low, p): plist.append(p) p += 2 else: p += 2 while q<2: #Will stop just after we pass the test, for the first time low = primes2.low(primes2.lim(p)+1, plist) #Standard parallel prime sieve if primes2.divtest(low, p): plist.append(p) res.append((p, 1)) #In this case, we are returning prime factorization, not just a prime list num *= (p+1) #Exponent, of one, not infinity, here; must be remembered den *= p q = num/den #Reset the quotioned p += 2 else: p += 2 return (den, res) #As the denominator is the product of the primes, it is also the sought-after number. res is its pf. else: c = primelist[n:] i = 0 num = 1 den = 1 q = 1 res = [] while q<2: res.append((c[i], 1)) num *= (c[i] + 1) den *= c[i] q = num/den i += 1 return (den, res)
def lastprime(factors, primelist = None): """Finds the last prime such that the list of primes in factors and that prime are the distinct prime factorization of at least one primitive abundant number""" if primelist == None: # . . . then yet another parallel prime sieve. M = maxdef(factors) #We need the maximum deficiency of the set of numbers if M == None: #If there is no maximum deficiency to speak of . . . return None #There is no last prime if M[1] == 2: #If this was one of those infinite perfect numbers (only known: 2**inifinity), we don't want an infinite loop return "all primes valid" # . . . as there is no last prime num = M[-2] #Otherwise, we read off num and den from the maximum deficiency den = M[-1] cand = [] #This is the list of all the primes that satisfy the conditions, except the last element plist = [2] #We must include the oddest prime, as all we will check is odd numbers. p = 1 #Because it is 2 less than three, and here, on a whim, I decided to increment at the beginning of the loop. q, r = 3, 0 #Bogus passing values. while test(q,r): # . . . while we are still dealing with satisfactory primes. p += 2 #Increment our prime l = int(p**0.5) #Standard parallel prime sieve. low = primes2.low(primes2.lim(p)+1, plist) if primes2.divtest(low, p): #If p is prime plist.append(p) #We add it to the list of primes. if p not in factors: #We don't want repetitions cand.append(p) #Add it to the list of candidates, . . . a, b = num*p, den*(p-1) q, r = a/b, a%b #And recaluculate q and r if len(cand) <= 1: #If the first new prime failed . . . return None #Then there is no last passing prime else: return cand[-2] #Otherwise, we return the last prime that did not fail. else: M = maxdef(factors) #Same as above, but without the parallel prime sieve. if M == None: return None if M[1] == 2: return "all primes valid" num = M[-2] den = M[-1] m = max(factors) c = [x for x in primelist if x > m] i = -1 q, r = 3, 0 while test(q, r): i += 1 p = c[i] a = num*p b = den*(p-1) q, r = a/b, a%b if i == 0: return None else: return c[i-1]