def Solve(): primes = [x for x in PrimeSieve(18)][::-1] digits = set([str(x) for x in range(0, 10)]) candidates = [] # find all possible combinations for last 3 digits for test in range(0, 1000, primes[0]): testStr = str(test).zfill(3) # test the digits directly rather using `set` object, massive speed difference # if len(set(d for d in testStr)) == len(testStr): if testStr[0] != testStr[1] != testStr[2] and testStr[0] != testStr[2]: candidates.append((testStr, digits - set([d for d in testStr]))) for p in primes[1:]: nextCandidates = [] for cand in candidates: for nextDig in cand[1]: testStr = nextDig + cand[0][:2] if int(testStr) % p == 0: setDigits = nextDig + cand[0] nextCandidates.append( (setDigits, digits - set([d for d in setDigits]))) candidates = nextCandidates[:] # convert the candidate values from strings to numbers candidates = [int(x[1].pop() + x[0]) for x in candidates] return (sum(candidates))
def Solve(p=600851475143): prime = PrimeSieve() f = next(prime) while not p == 1: if p % f == 0: p = p / f else: f = next(prime) return f
def Solve(limit=1_000_000): prime = PrimeSieve(valLimit=limit) prod = 1 while prod < limit: p = next(prime) prod *= p prod = prod // p return prod
def Solve(): limit = 1000000 primes = [x for x in PrimeSieve(limit)] maxLength = 1 maxPrime = 2 for i in range(0,len(primes)-1): length = maxLength if i+length > len(primes): break sumPrime = sum(primes[i:i + length]) while sumPrime < limit: if sumPrime in primes: maxLength = length maxPrime = sumPrime sumPrime += primes[i+length] length += 1 return(maxPrime)
def Solve(): limit = 1000000 primes = set(PrimeSieve(limit)) CircPrimes = set() for n in set(primes): if n >= 10: digits = set(int(x) for x in str(n)) if digits.intersection(range(0, 10, 2)): primes.remove(n) elif 5 in digits: primes.remove(n) def rotate(n): z = list(str(n)) z = z[1:] + z[:1] return(int(''.join(z))) for i in primes: if i in CircPrimes: continue else: n = i temp = set() while n not in temp: if n not in primes: break else: temp.add(n) n = rotate(n) else: CircPrimes.update(temp) return(len(CircPrimes))
def Solve2(): target = 5 # cheat: use the finite sieve since I already know the answer. sieve = PrimeSieve(10**4) # prime the data so that we exclude 2 and 5. 2 and 5 will never be part of a set that meets the condition. # this invalidates a target value of 1, but that case is trivial (it's 2). as we enter the loop, it will look like # we ran the loop to generate 2,3,5,7 and then dropped 2 and 5 from primes and removed sets containing them from # valid sets primes = [next(sieve) for x in range(4)] primes.remove(2) primes.remove(5) validSets = [{3}] primeIndex = len(primes) - 1 while True: nextPrime = primes[primeIndex] while nextPrime >= max(primes): primes.append(next(sieve)) nextValidSets = validSets[:] append = nextValidSets.append append({nextPrime}) pairsWith = set() add = pairsWith.add for p in primes: if IsPrime(int(str(p) + str(nextPrime))): if (int(str(nextPrime) + str(p))) in primes: add(p) for currentSet in validSets: if currentSet - pairsWith == set(): candidateSet = set(currentSet) candidateSet.add(nextPrime) if len(candidateSet) >= target: return sum(candidateSet) append(set(candidateSet)) validSets = nextValidSets primeIndex += 1
def Solve3(): # my original algorithm. naive. VERY SLOW! numbers = permutations([x for x in range(0, 10)]) #exclude numbers starting in 0 and numbers which will not meet condition for 5 numbers = [x for x in numbers if x[0] != 0 or x[5] != 0] primes = [x for x in PrimeSieve(18)] temp = 0 for n in numbers: counter = 1 while counter <= len(primes): test = int(''.join([str(x) for x in n[counter:counter + 3]])) if test % primes[counter - 1] != 0: break counter += 1 if counter > len(primes): temp += int(''.join([str(x) for x in n])) return (temp)
def Solve1(target=5): sieve = PrimeSieve(float('inf')) def TestPair(a, b): if not IsPrime(int(str(a) + str(b))): return (False) if not IsPrime(int(str(b) + str(a))): return (False) return (True) def TestCanAdd(current, new): for c in current: if not TestPair(c, new): return (False) return (True) [next(sieve) for x in range(3)] validSets = [{3}] while True: p = next(sieve) currentSets = validSets[:] for set in currentSets: temp = set.copy() if TestCanAdd(temp, p): temp.add(p) if len(temp) == target: return (sum(temp)) validSets.append(temp) validSets.append({p})
def Solve(target=5): sieve = PrimeSieve(float('inf')) def TestPair(a, b): if not IsPrime(int(str(a) + str(b))): return False if not IsPrime(int(str(b) + str(a))): return False return True # prime the data so that we exclude 2 and 5. 2 and 5 will never be part # of a set that meets the condition. this invalidates a target value of 1, # but that case is trivial (it's 2). as we enter the loop, it will look # like we ran the loop to generate 2,3,5,7 and then dropped 2 and 5 from # primes and removed sets containing them from valid sets if target == 1: return (2) primes = [next(sieve) for x in range(3)] primes.remove(2) primes.remove(5) validSets = [{3}] # run until we find a solution while True: # move to the next prime p1 = next(sieve) # make a copy so that we can loop through it and add to the original loopSets = validSets[:] # loop through all smaller primes and build a set of primes that the # new one will work with pairsWith = set() for p0 in primes: if TestPair(p0, p1): pairsWith.add(p0) # check each of the existing sets to see if we can add the new prime # to each of them. for currentSet in loopSets: # use set difference to make sure the new prime is compatible with # all primes in the set we're checking if currentSet - pairsWith == set(): # construct a new valid set candidateSet = currentSet.copy() candidateSet.add(p1) # if the new set has the desired length we're done if len(candidateSet) == target: return sum(candidateSet) # if we're not done then we need to extend the list of # valid sets validSets.append(set(candidateSet)) # the new prime by itself is a valid set validSets.append({p1}) # add the new prime to the list of primes primes.append(p1)