def solve_problem(): # We know we are looking for a number with 5 digits or more # let's assume 5 to 6 digits primes = [prime for prime in list_primes(1000000) if prime > 10000] # Now we've got to sort out the ones that that have three repeating digits # excepting the last digit # TODO : Correct this goddamn shitty regex that is almost right but not quite so. # What if the repeating digit is the first one ? # pattern = re.compile(r"([0-9])*([^\\1])[^\\2]*\2[^\\2]*\2[^\\2]+") pattern = re.compile(r"(\d)\d*\1\d*\1\d+$") primes = [prime for prime in primes if pattern.match(str(prime))] # Take all the primes left and roll the repeating digits # check if the new number exists in the list of primes # if there are 8 matches, we good ;) #shorten the primes for debbuging purposes for index, prime in enumerate(primes): tmp_prime = str(prime) #fil = filter(lambda c: c == "0", tmp_prime) for repeating_digit in range(3): # make a filter that tells which digit is repeating fil = [ "1" if c == str(repeating_digit) else "0" for c in tmp_prime ] # transform the filter in a multiple that we can add to our prime to change positional digits if fil.count("1") == 3: diff = int("".join(fil)) generated = [ prime + mul * diff for mul in range(10 - repeating_digit) if prime + mul * diff in primes ] if len(generated) == 8: print(generated[0]) return 0
def solve_problem(): # We know we are looking for a number with 5 digits or more # let's assume 5 to 6 digits primes = [prime for prime in list_primes(1000000) if prime > 10000] # Now we've got to sort out the ones that that have three repeating digits # excepting the last digit # TODO : Correct this goddamn shitty regex that is almost right but not quite so. # What if the repeating digit is the first one ? # pattern = re.compile(r"([0-9])*([^\\1])[^\\2]*\2[^\\2]*\2[^\\2]+") pattern = re.compile(r"(\d)\d*\1\d*\1\d+$") primes = [prime for prime in primes if pattern.match(str(prime))] # Take all the primes left and roll the repeating digits # check if the new number exists in the list of primes # if there are 8 matches, we good ;) #shorten the primes for debbuging purposes for index, prime in enumerate(primes): tmp_prime = str(prime) #fil = filter(lambda c: c == "0", tmp_prime) for repeating_digit in range(3): # make a filter that tells which digit is repeating fil = ["1" if c == str(repeating_digit) else "0" for c in tmp_prime] # transform the filter in a multiple that we can add to our prime to change positional digits if fil.count("1") == 3: diff = int("".join(fil)) generated = [prime + mul * diff for mul in range(10 - repeating_digit) if prime + mul * diff in primes] if len(generated) == 8: print(generated[0]) return 0
Problem : Which prime, below one-million, can be written as the sum of the most consecutive primes? Performance time: ~12s """ from primes import list_primes from primes import generate_primes from timer import timer timer.start() primes = list_primes(1000000) max_seq, total, answer = 0, 0, 0 for index in range(len(primes)): total = 0 for count, prime in enumerate(primes[index:]): total += prime if total > answer and count > max_seq and total in primes: answer = total max_seq = count elif total > 1000000: break print(answer) timer.stop()
The answer must be an odd number. Twice a square is always even, add prime makes it always odd (except if the prime is 2) Assumption : The answer is < 1000000 Performance time: ~22s """ from primes import list_primes from timer import timer timer.start() primes = set(list_primes(1000000)) composites = set(set(range(9, 1000000, 2)).difference(primes)) goldbach = set() for prime in primes: for twice_a_square in range(int((1000000 - prime) ** 0.5)): g = prime + 2 * twice_a_square ** 2 if g < 1000000: goldbach.add(g) else: break print(min(composites.difference(goldbach))) timer.stop()
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. Performance time: ~5.9s """ from collections import OrderedDict from primes import list_primes from timer import timer timer.start() primes = list_primes(10000) primes_check = set(list_primes(99999999)) # Prime combinations # Where one prime entry indicates all primes higher than itself with whom it can compose another prime pairs = OrderedDict() for index, prime in enumerate(primes): #print("Generation at {:.2f}%".format(index / len(primes) * 100)) pairs[prime] = [ p for p in primes[index + 1:] if int("{}{}".format(prime, p)) in primes_check and int("{}{}".format(p, prime)) in primes_check ] for i, k in enumerate(pairs): #print("Intersection checks at {:.2f}%".format(i/len(pairs) * 100))
def consecutive_quadratic_primes(a, b): """ Returns the amount of consecutive prime yielded by n**2 + an + b by counting forward, from n = 0 """ for n in count(start=0): if not is_prime(n**2 + a * n + b): return n timer.start() primes = [] for prime in list_primes(1000): primes += [prime, -prime] max_serie = 0 answer = None for a in range(-1000, 1000): for b in primes: serie_length = consecutive_quadratic_primes(a, b) if serie_length > max_serie: max_serie = serie_length answer = a * b print(answer) timer.stop()
""" Problem : Find the sum of all the primes below two million. Performance time: ~0.08s """ from timer import timer from primes import list_primes timer.start() print(sum(list_primes(2000000))) timer.stop()
""" from primes import list_primes from timer import timer timer.start() min_nphin = 10000000 answer = 0 # sort the primes, where the closest to sqrt(10⁷) come first # This because of the mean inequality theorem # (The biggest area of a given perimeter will be square) primes = list_primes(10000000) primes.sort(key=lambda x: abs(((10000000) ** 0.5) - x)) for big in reversed(primes): for small in primes: n = big * small if n > 10000000: break phin = (big - 1) * (small - 1) if sorted(str(phin)) == sorted(str(n)): nphin = n / phin if nphin < min_nphin: min_nphin = nphin answer = n break #not sure I should break here print(answer)
There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence. What 12-digit number do you form by concatenating the three terms in this sequence? Performance time: ~0.0056s """ from primes import list_primes from timer import timer timer.start() primes = [prime for prime in list_primes(10000) if prime > 1000] lower_third = [prime for prime in primes if prime < 3333 and prime != 1487] for prime in lower_third: sequence = [prime, prime + 3330, prime + 6660] if sequence[1] not in primes or sequence[2] not in primes: continue else: if sorted(str(sequence[0])) == \ sorted(str(sequence[1])) == \ sorted(str(sequence[2])): print("{}{}{}".format(prime, prime + 3330, prime + 2 * 3330)) timer.stop()
primes, exhibiting this property, but there is one other 4-digit increasing sequence. What 12-digit number do you form by concatenating the three terms in this sequence? Performance time: ~0.0056s """ from primes import list_primes from timer import timer timer.start() primes = [prime for prime in list_primes(10000) if prime > 1000] lower_third = [prime for prime in primes if prime < 3333 and prime != 1487] for prime in lower_third: sequence = [prime, prime+3330, prime+6660] if sequence[1] not in primes or sequence[2] not in primes: continue else: if sorted(str(sequence[0])) == \ sorted(str(sequence[1])) == \ sorted(str(sequence[2])): print("{}{}{}".format(prime, prime + 3330, prime + 2*3330)) timer.stop()
def consecutive_quadratic_primes(a, b): """ Returns the amount of consecutive prime yielded by n**2 + an + b by counting forward, from n = 0 """ for n in count(start=0): if not is_prime(n**2 + a*n + b): return n timer.start() primes = [] for prime in list_primes(1000): primes += [prime, -prime] max_serie = 0 answer = None for a in range(-1000, 1000): for b in primes: serie_length = consecutive_quadratic_primes(a, b) if serie_length > max_serie: max_serie = serie_length answer = a * b print(answer) timer.stop()
Nota bene : The answer must be an odd number. Twice a square is always even, add prime makes it always odd (except if the prime is 2) Assumption : The answer is < 1000000 Performance time: ~22s """ from primes import list_primes from timer import timer timer.start() primes = set(list_primes(1000000)) composites = set(set(range(9, 1000000, 2)).difference(primes)) goldbach = set() for prime in primes: for twice_a_square in range(int((1000000 - prime)**0.5)): g = prime + 2 * twice_a_square**2 if g < 1000000: goldbach.add(g) else: break print(min(composites.difference(goldbach))) timer.stop()
Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime. Performance time: ~5.9s """ from collections import OrderedDict from primes import list_primes from timer import timer timer.start() primes = list_primes(10000) primes_check = set(list_primes(99999999)) # Prime combinations # Where one prime entry indicates all primes higher than itself with whom it can compose another prime pairs = OrderedDict() for index, prime in enumerate(primes): #print("Generation at {:.2f}%".format(index / len(primes) * 100)) pairs[prime] = [p for p in primes[index+1:] if int("{}{}".format(prime, p)) in primes_check and int("{}{}".format(p, prime)) in primes_check] for i, k in enumerate(pairs): #print("Intersection checks at {:.2f}%".format(i/len(pairs) * 100)) c1 = pairs[k] if len(c1) >= 4: for k1 in c1:
""" Problem : Find the sum of all the primes below two million. Performance time: ~0.08s """ from timer import timer from primes import list_primes timer.start() print(sum(list_primes(2000000))) timer.stop()