def solve(primelimit=10000): start = time() primes = primesbelow(primelimit) primes = [3] + primes[3:] # 2 and 5 will not be part of the set largeprimes = set(primesbelow(primelimit**2)) result = 5 * primes[-1] pairs = [[False for col in range(row)] for row in range(len(primes))] for p1 in range(len(primes)): for p2 in range(p1): if concat(primes[p1], primes[p2]) in largeprimes \ and concat(primes[p2], primes[p1]) in largeprimes: pairs[p1][p2] = True for p3 in range(p2): if pairs[p1][p3] and pairs[p2][p3]: for p4 in range(p3): if pairs[p1][p4] and pairs[p2][p4] \ and pairs[p3][p4]: for p5 in range(p4): if pairs[p1][p5] and pairs[p2][p5] \ and pairs[p3][p5] and pairs[p4][p5]: primetotal = primes[p1] + primes[p2] + \ primes[p3] + primes[p4] + primes[p5] if primetotal < result: result = primetotal peresult(60, result, time() - start)
def solve(m=10**5): cap = 3 * 10**6 # by experimentation, this is enough primes = primesbelow(cap) count = 0 sieve = [True for x in range(cap)] for i in range(1, cap): if sieve[i]: is_valid = True for f in [1, 2, 4, 7, 11, 14, 22, 28, 44, 77, 154, 308]: z = f * i + 1 # Test if z is prime. If it is, we have an issue. if z in [2, 3, 5, 23, 29]: # ...unless it's already a divisor of 20010. continue z_is_prime = True for p in primes: if p**2 > z: break if z % p == 0: z_is_prime = False break if z_is_prime: is_valid = False break if is_valid: count += 1 #print(count, i, 308 * i, sep='\t') if count == m: return 308 * i else: for mult in range(i, cap, i): sieve[mult] = False
def solve(): cap = 2**50 result = cap primes = primesbelow(int(sqrt(cap)) + 1) for i in range(len(primes)): primes[i] = primes[i]**2 primes.append(cap + 1) # So technically 'primes' is inaccurate but whatever for primecount in count(1): indices = list(range(primecount)) term = listprod(primes, indices) if term > cap: return result while True: if term <= cap: result += (cap // term) * pow(-1, primecount) term //= primes[indices[-1]] term *= primes[indices[-1] + 1] indices[-1] += 1 else: # Are there any nonconsecutive indices? if indices[-1] == indices[0] + primecount - 1: break # If so, advance the last nonconsecutive index. for i in range(primecount - 2, -1, -1): if indices[i] != indices[i + 1] - 1: indices[i] += 1 for j in range(i + 1, primecount): indices[j] = indices[j - 1] + 1 term = listprod(primes, indices) break
def solve(primelimit, hamminglimit): start = time() primes = primesbelow(primelimit + 1) exponents = [0 for x in range(len(primes))] index = 0 hamming = 1 count = 0 while True: if hamming > hamminglimit: hamming //= primes[index] ** exponents[index] exponents[index] = 0 if index == 0: break else: exponents[index - 1] += 1 hamming *= primes[index - 1] index -= 1 else: if index == len(primes) - 1: count += 1 exponents[index] += 1 hamming *= primes[index] else: index += 1 peresult(204, count, time() - start)
def solve(): primes = set(primesbelow(10**6)) def is_trunc_prime(num): # Trim from the right right_trim = num // 10 while right_trim > 0: if right_trim not in primes: return False right_trim //= 10 # Trim from the left ten_pow = 10 while ten_pow * 10 < num: ten_pow *= 10 while num > 0: if num not in primes: return False num %= ten_pow ten_pow //= 10 return True count = 0 total = 0 for prime in primes: if is_trunc_prime(prime): count += 1 total += prime if count == 15: # counting 2, 3, 5, and 7... return total - 17 # ...and then uncounting them print("Error: Cap on primes too low")
def solve(cap = 20000): mod = 1000000007 primes = primesbelow(cap + 1) bf = [0 for p in primes] # Factors of B(n) ff = [0 for p in primes] # Factors of n! result = 0 for n in range(1, cap + 1): D = 1 N = n # A copy to determine the prime factors for i in range(len(primes)): p = primes[i] exp = 0 while N % p == 0: exp += 1 N //= p ff[i] += exp if ff[i] == 0: break bf[i] += exp * n - ff[i] D *= pow(p, bf[i] + 1, mod) - 1 D *= pow(p - 1, mod - 2, mod) D %= mod result += D result %= mod return result
def solve(cap = 10 ** 7): # Step 1: Get prime decomposition and totient of all integers primes = primesbelow(cap + 1) decomp = [ [] for x in range(cap + 1)] totient = [x for x in range(cap + 1)] for p in primes: for mult in range(p, cap + 1, p): decomp[mult].append(p) totient[mult] = totient[mult] * (p - 1) // p power = p while power <= cap: power *= p for mult in range(power, cap + 1, power): decomp[mult][-1] = power # Step 2: For each integer, analyze all possible x and y, and take max a result = 0 # Skipping 1 because M(1) = 0 for n in range(2, cap + 1): factors = [1] for d in decomp[n]: factors = factors + [d * f for f in factors] max_a = 0 for x in factors: y = n // x max_a = max(max_a, x * pow(x, totient[y] - 1, y)) result += max_a return result
def solve(cap=1000000): primes = primesbelow(cap) # Find max number of primes that, when concatenated, sum to less than cap initial_prime_sum = 0 end_index = -1 while initial_prime_sum + primes[end_index + 1] < cap: end_index += 1 initial_prime_sum += primes[end_index] if initial_prime_sum in primes: return initial_prime_sum # This probably won't happen, but safety first for length in range(end_index + 1, 0, -1): # initial_prime_sum is the max sum below cap of primes with given length start_index = end_index - length + 1 while initial_prime_sum - primes[start_index] + primes[end_index] < cap: initial_prime_sum += -primes[start_index] + primes[end_index] end_index += 1 start_index += 1 # Add a prime to the beginning and trim a prime from the end # Do this until either we run out of primes or the total is prime new_prime_sum = initial_prime_sum new_end_index = end_index new_start_index = start_index while new_prime_sum not in primes and new_start_index > 0: new_start_index -= 1 new_end_index -= 1 new_prime_sum += primes[new_start_index] - primes[new_end_index + 1] if new_prime_sum in primes: return new_prime_sum # No chains of given length sum to a prime. Trim one from the start initial_prime_sum -= primes[start_index]
def solve(cap = 10 ** 16): primes = primesbelow(100) mat = [ [0 for col in range(len(primes)-2)] for row in range(len(primes)-3)] for row in range(len(primes) - 3): for col in range(row + 1): mat[row][col] = choose(row + 4, col + 4) mat[row][-1] = 1 multipliers = matsolve(mat) multipliers = list(map(int, multipliers)) result = 0 for length in range(4, len(primes)): indices = [i for i in range(length)] while True: term = (cap - 1) // (subproduct(primes, indices)) result += multipliers[length - 4] * term # Move the rightmost index that we can right. # (except for the absolute rightmost index # if the term is zero; that would be pointless) if term != 0 and indices[-1] != len(primes) - 1: indices[-1] += 1 continue for i in range(len(indices) - 2, -1, -1): if indices[i] + 1 != indices[i + 1]: for j in range(len(indices) - 1, i - 1, -1): indices[j] = indices[i] + j - i + 1 break else: # We've found all we can for this index count break return result
def solve(cap=10**8): primes = primesbelow(cap) result = 0 for p in primes[2:]: # Ignoring 2 and 3 if p % 4 == 1: result += -3 * (p**2 - 2 * p + 1) // 8 % p else: result += -3 * (3 * p**2 - 4 * p + 1) // 8 % p return result
def solve(n=10**7, k=10**5, mod=10007): primes = [0] + primesbelow(20 * n) # avoiding index issues print("Found primes") S = [pow(primes[i], i, mod) for i in range(len(primes))] print("Created S") S2 = [S[i] + S[(i // 10000) + 1] for i in range(len(primes))] print("Created S2") # Populate initial data set vals = [0 for x in range(2 * mod - 1)] for i in range(1, k + 1): vals[S2[i]] += 1 # Find initial medians remaining = k // 2 for x in range(len(vals)): if vals[x] < remaining: remaining -= vals[x] else: low_med = [x, remaining] if remaining == vals[x]: high_med = [x + 1, 1] while vals[high_med[0]] == 0: high_med[0] += 1 else: high_med = [x, remaining + 1] break result = low_med[0] + high_med[0] # Rotate in elements of S2 for i in range(k + 1, n + 1): old = S2[i - k] new = S2[i] vals[old] -= 1 vals[new] += 1 for med in (low_med, high_med): if new < med[0] and old >= med[0]: # Decrease the median if med[1] > 1: med[1] -= 1 else: # Top of the next lowest stack med[0] -= 1 while vals[med[0]] == 0: med[0] -= 1 med[1] = vals[med[0]] elif (old < med[0] and new >= med[0]) or \ (old == med[0] and new > med[0] and vals[med[0]] < med[1]): # Increase the median if med[1] < vals[med[0]]: med[1] += 1 else: # Bottom of the next highest stack med[0] += 1 while vals[med[0]] == 0: med[0] += 1 med[1] = 1 result += low_med[0] + high_med[0] #print(vals, low_med, high_med, sep='\t') return result / 2
def solve(cap=1000000): primes = primesbelow(cap) primes.append(primeabove(primes[-1])) ten_power = 1 result = 0 for i in range(2, len(primes) - 1): if ten_power < primes[i]: ten_power *= 10 d = pow(ten_power, primes[i + 1] - 2, primes[i + 1]) result += ((-primes[i] * d) % primes[i + 1]) * ten_power + primes[i] return result
def solve(): primes = primesbelow(33) for odd in count(35, 2): if isprime(odd): primes.append(odd) continue for prime in primes: if sqrt((odd - prime) // 2) % 1 == 0: break else: return odd
def solve(): start = time() print("Note: This one takes a while. Don't know how to get it under 60s.") mod = 10 ** 16 primes = primesbelow(5000) totalLargest = 1 for p in primes: totalLargest += p subsetCounts = [1] + [0 for x in range(totalLargest)] currentLargest = 0 for p in primes: currentLargest += p for newSum in range(currentLargest, p-1, -1): subsetCounts[newSum] += subsetCounts[newSum - p] subsetCounts[newSum] %= mod largeprimes = primesbelow(totalLargest) result = 0 for lp in largeprimes: result += subsetCounts[lp] result %= mod peresult(249, result, time() - start)
def solve(cap=1000): b_list = primesbelow(cap) # b must be prime (consider n = 0) longest_streak = 0 result = 0 for a in range(-cap, cap + 1): for b in b_list: n = 1 while isprime(n**2 + a * n + b): n += 1 if n - 1 > longest_streak: longest_streak = n - 1 result = a * b return result
def solve(): primes = primesbelow(10000) for index1 in range(len(primes) - 1): if primes[index1] < 1000 or primes[index1] == 1487: continue prime1 = primes[index1] for index2 in range(index1 + 1, len(primes)): prime2 = primes[index2] if not arePermutes(prime1, prime2): continue testprime = 2 * prime2 - prime1 if testprime in primes and arePermutes(prime1, testprime): return str(prime1) + str(prime2) + str(testprime)
def solve(k=10**9): count = 0 result = 0 primes = primesbelow(10**6) # this should be enough if k % 3 == 0: count = 1 result = 3 for p in primes[2:]: if pow(10, k, p) == 1: count += 1 result += p if count == 40: return result raise RuntimeError("Prime cap is too low")
def solve(larger, smaller): start = time() primes = primesbelow(larger) result = 0 for p in primes: power = 1 factorcount = 0 while p**power <= larger: factorcount += larger // (p**power) factorcount -= (larger - smaller) // (p**power) factorcount -= smaller // (p**power) power += 1 result += p * factorcount peresult(231, result, time() - start)
def solve(cap): start = time() print("Note: This one takes just a LITTLE over a minute, but since it's" \ + " pretty close and in Python, I'm calling it good enough.") rawPrimes = primesbelow(cap) maxLink = dict() #Largest element in chain from 2 to prime (minimized) for prime in rawPrimes: maxLink[prime] = cap + 1 maxLink[2] = 2 currentPrimes = {2} while len(currentPrimes) > 0: newPrimes = set() for prime in currentPrimes: #Replace a digit clone = prime power = 0 while clone > 0: currentDigit = clone % 10 #Decrease a digit for diff in range(1, currentDigit + 1): possibleNew = prime - (diff * (10**power)) if possibleNew in maxLink \ and maxLink[prime] < maxLink[possibleNew]: maxLink[possibleNew] = max(possibleNew, maxLink[prime]) newPrimes.add(possibleNew) #Increase a digit for diff in range(1, 10 - currentDigit): possibleNew = prime + (diff * (10**power)) if possibleNew in maxLink \ and maxLink[possibleNew] > max(possibleNew, \ maxLink[prime]): maxLink[possibleNew] = max(possibleNew, maxLink[prime]) newPrimes.add(possibleNew) clone //= 10 power += 1 #Add a digit on the left for dig in range(1, 10): possibleNew = ((10**power) * dig) + prime if possibleNew in maxLink \ and maxLink[possibleNew] > max(possibleNew, \ maxLink[prime]): maxLink[possibleNew] = max(possibleNew, maxLink[prime]) newPrimes.add(possibleNew) currentPrimes = newPrimes result = 0 for prime in maxLink.keys(): if maxLink[prime] > prime: result += prime peresult(425, result, time() - start)
def solve(cap): start = time() primes = primesbelow(cap) print("Finished finding primes") factorial = 1 #Factorial of p-5 result = 4 #p=5 is a special case so I'm ignoring it nextIndex = 3 #Index of the next prime to be examined counter = 6 while nextIndex < len(primes): factorial *= counter - 5 if counter == primes[nextIndex]: result += (9 * factorial) % primes[nextIndex] nextIndex += 1 counter += 1 peresult(381, result, time() - start)
def solve(n=10**18, k=10**9): primes = [p for p in primesbelow(5000) if p > 1000] mods = [0 for p in primes] # Step 1: Find C(n, k) mod p for all p for i in range(len(primes)): p = primes[i] # First, find out if the mod is 0 if fact_prime(n, p) - fact_prime(n - k, p) > fact_prime(k, p): print(p, 0) continue # Since the mod isn't 0, compute it mods[i] = 1 for j in range(1, k % p + 1): mods[i] *= (n + 1 - j) * pow(j, p - 2, p) mods[i] %= p # EXPERIMENTAL for mult in range((n // p) * p, n - k, -p): temp = mult while temp % p == 0: temp //= p mods[i] *= temp mods[i] %= p for mult in range(p, k + 1, p): temp = mult while temp % p == 0: temp //= p mods[i] *= pow(temp, p - 2, p) mods[i] %= p print(p, mods[i]) # Step 2: Find the result over all triples of primes result = 0 for i1 in range(len(primes) - 2): print(primes[i1]) for i2 in range(i1 + 1, len(primes) - 1): # Run the Extended Euclidean Algorithm over the first two primes p, q = primes[i1], primes[i2] (s, t) = extended_euclidean(p, q) partial = (mods[i1] * t * q + mods[i2] * s * p) % (p * q) for i3 in range(i2 + 1, len(primes)): # Run the algorithm again with the third prime r = primes[i3] (s, t) = extended_euclidean(p * q, r) term = (partial * t * r + mods[i3] * s * p * q) % (p * q * r) # if mods[i1] and mods[i2] and mods[i3]: # print(partial, p * q, mods[i3], r, term) #print('', p, q, r, term, sep='\t') result += term return result
def solve(cap): start = time() result = 0 primes = primesbelow(cap) primes.pop(1) # 3 returns a false positive for the test below, # because 3 divides 10^2 - 1, but not R(2) for p in primes: x = p - 1 while x % 2 == 0: x //= 2 while x % 5 == 0: x //= 5 if pow(10, (p - 1) // x, p) != 1: result += p result += 3 # Need to add 3 back in peresult(133, result, time() - start)
def solve(cap = 190): primes = primesbelow(cap) target = log(product(primes)) * 0.5 combos_a = log_combos((p for p in primes[:len(primes) // 2]), target) combos_b = log_combos((p for p in primes[len(primes) // 2:]), target) best_answer = 1 for a in combos_a: left, right = 0, len(combos_b) - 1 while right - left > 1: mid = (left + right) // 2 if a[0] + combos_b[mid][0] < target: left = mid else: right = mid new_answer = product(a[1]) * product(combos_b[left][1]) best_answer = max(best_answer, new_answer) return best_answer % (10 ** 16)
def solve(): start = time() mod = 1234567891011 primes = primesbelow(10 ** 7 + 2) #Sieve represents numbers from 10**14 to 10**14+10**7-1 sieve = [True for x in range(10 ** 7)] for p in primes: lowestMultiple = (10 ** 14) // p * p if lowestMultiple < 10 ** 14: lowestMultiple += p for multiple in range(lowestMultiple - 10 ** 14, len(sieve), p): sieve[multiple] = False primes = [] #Might as well reuse the array name for index in range(len(sieve)): if len(primes) >= 100000: break if sieve[index]: primes.append(index) matpows = [[1, 1, 1, 0]] for twopow in range(47): #just to be safe newmat = matrixmult(matpows[-1], matpows[-1]) for index in range(len(newmat)): newmat[index] %= mod matpows.append(newmat) index1 = primes[0] + (10 ** 14) - 1 matrix = [1, 1, 1, 0] while index1 > 0: power = 0 while 2 ** (power + 1) < index1: power += 1 matrix = matrixmult(matrix, matpows[power]) index1 -= 2 ** power result = matrix[1] for index in range(1, len(primes)): stepsLeft = primes[index] - primes[index - 1] while stepsLeft > 0: power = 0 while 2 ** (power + 1) < stepsLeft: power += 1 matrix = matrixmult(matrix, matpows[power]) for index in range(len(matrix)): matrix[index] %= mod stepsLeft -= 2 ** power result += matrix[1] result %= mod peresult(304, result, time() - start)
def solve(cap = 15499/94744): start = time() primes = primesbelow(100) # Safe overestimate numerator = 1 n = 1 for p in primes: if (numerator * (p - 1)) / (n * p - 1) > cap: numerator *= p - 1 n *= p else: for mult in range(1, p): if (numerator * mult) / (n * mult - 1) < cap: result = n * mult break break else: # Loop fell through. Primes list wasn't long enough raise RuntimeError("Primes list in code too short. Edit and extend") peresult(243, result, time() - start)
def solve(): start = time() mod = 10 ** 9 fibo = [1, 2] for x in range(21): # Last element is 24th fibonacci number fibo.append(fibo[-1] + fibo[-2]) primes = primesbelow(fibo[-1]) sums = [0 for x in range(fibo[-1] + 1)] # sums[k] == S(k, p) at end of loop sums[0] = 1 # 1 is the only integer whose prime factors sum to 0 for p in primes: for k in range(p, len(sums)): sums[k] += p * sums[k - p] sums[k] %= mod result = 0 for f in fibo: result += sums[f] result %= mod peresult(618, result, time() - start)
def solve(): start = time() primes = primesbelow(int(10**4.5) + 1) exponents = [] admissible = 1 pointer = 0 while admissible * primes[pointer] < 10**9: admissible *= primes[pointer] exponents.append(1) pointer += 1 pseudos = set() while len(exponents) > 0: #Add the pseudo-Fortunate number for this admissible number pseudo = 2 pseudoIsGood = False while not pseudoIsGood: for prime in primes: if (admissible + pseudo) % prime == 0: pseudo += 1 break if prime**2 > admissible + pseudo or prime == primes[-1]: pseudos.add(pseudo) pseudoIsGood = True break #Find the next admissible number admissible *= primes[0] exponents[0] += 1 pointer = 0 while admissible >= 10**9: if pointer == len(exponents) - 1: admissible //= primes[pointer]**exponents[pointer] del exponents[pointer] break else: admissible //= primes[pointer]**(exponents[pointer] - 1) exponents[pointer] = 1 admissible *= primes[pointer + 1] exponents[pointer + 1] += 1 pointer += 1 result = sum(pseudos) peresult(293, result, time() - start)
def solve(s=60): big = (2**s) - 1 # Step 1: Factor big all_primes = primesbelow(1400) # No larger primes divide 2^60-1 primes, exp_cap = [], [] for p in all_primes: if big % p == 0: primes.append(p) exp = 1 while (big // (p**exp)) % p == 0: exp += 1 exp_cap.append(exp) # Step 2: Find all 2^m-1 smaller than big cant_divide = [] for two_exp in range(2, s): cant_divide.append((2**two_exp) - 1) # Step 3: Iterate among all factors of big. # If they don't divide any other 2^m-1, add one plus them to the answer factor = 1 exp = [0 for p in primes] result = 0 while True: # Find the next factor of big index = 0 while index < len(primes) and exp[index] == exp_cap[index]: factor //= primes[index]**exp[index] exp[index] = 0 index += 1 if index == len(primes): return result factor *= primes[index] exp[index] += 1 # We have a factor; time to see if it works for bad in cant_divide: if bad % factor == 0: break else: result += factor + 1
def solve(limit): start = time() primes = primesbelow(int(limit**.5) + 1) result = 0 for ind in range(len(primes) - 1): lowPrime = primes[ind] highPrime = primes[ind + 1] lowSquare = lowPrime**2 highSquare = highPrime**2 #Adding multiples of lowPrime bottomMult = lowSquare + lowPrime multCount = (highSquare - bottomMult) // lowPrime + 1 topMult = lowSquare + (multCount * lowPrime) result += multCount * (topMult + bottomMult) // 2 #Adding multiples of highPrime topMult = highSquare - highPrime multCount = (topMult - lowSquare) // highPrime + 1 bottomMult = highSquare - (multCount * highPrime) result += multCount * (topMult + bottomMult) // 2 #Subtracting multiple of both result -= 2 * lowPrime * highPrime #Case of final prime lowPrime = primes[-1] highPrime = primeabove(lowPrime) lowSquare = lowPrime**2 #Adding multiples of lowPrime bottomMult = lowSquare + lowPrime multCount = (limit - bottomMult) // lowPrime + 1 topMult = lowSquare + (multCount * lowPrime) result += multCount * (topMult + bottomMult) // 2 #Adding multiples of highPrime topMult = limit // highPrime * highPrime multCount = (topMult - lowSquare) // highPrime + 1 bottomMult = topMult - ((multCount - 1) * highPrime) result += multCount * (topMult + bottomMult) // 2 #Possibly subtracting multiple of both if lowPrime * highPrime <= limit: result -= 2 * lowPrime * highPrime #Result peresult(234, result, time() - start)
def solve(cap=50000000): start = time() mod = 1000000007 primes = primesbelow(cap + 1) + [cap + 1 ] # The append allows computation of # all S(n) where n is larger than # all primes below cap result = 6 c = 6 d = 6 pi = 0 for n in range(2, cap + 1): c = 6 * c - d if primes[pi] == n: # n is prime d = d * (n - 1) * modinv(pi + 1, mod) c += d pi += 1 else: # n is not prime d = d * (n - 1) * 5 * modinv(n - pi - 1, mod) c %= mod d %= mod result += c result %= mod peresult(423, result, time() - start)