''' The prime 41, can be written as the sum of six consecutive primes: 41 = 2 + 3 + 5 + 7 + 11 + 13 This is the longest sum of consecutive primes that adds to a prime below one-hundred. The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953. Which prime, below one-million, can be written as the sum of the most consecutive primes? ''' import math import numpy as np def sieve(n): assert n > 1 ns = [True] * n for i in range(2, math.ceil(np.sqrt(n))): if ns[i]: j = pow(i, 2) while j < n: ns[j] = False j = j + i return [i for i,val in enumerate(ns) if val][2:] # Note: this subset sum implementation only backtracks the sum with the smallest values as possible def subsetSum(elements, target): dyn = [] for _ in range(len(elements) + 1): dyn.append([True]) for _ in range(target): dyn[0].append(False) for i in range(1, len(elements) + 1): for j in range(1, target + 1): if elements[i-1] > j: dyn[i].append(dyn[i-1][j]) else: dyn[i].append(dyn[i-1][j] or dyn[i-1][j - elements[i-1]]) if not dyn[-1][-1]: return [] j = target i = len(elements) res = [] while j > 0: while dyn[i - 1][j]: i -= 1 curEl = elements[i - 1] j -= curEl res.append(curEl) return res def main(): print("Hello this is Patrick") target = 1000000 primeList = sieve(target) primeSet = set(primeList) numberofprimes = len(primeList) # s = 0 # n = 0 # while s < target: # s += primeList[n] # n += 1 # print(numberofprimes) # print(n - 1, s - primeList[n-1]) # So the number of options is very, very, very very large, we can't brute force this # print(math.factorial(numberofprimes) // (math.factorial(n-1) * math.factorial(numberofprimes - (n-1)))) # Additionally, this is exactly subset sum for all primes from big to small, since we probably want an as high as possible prime # longest = 0 # prime = 0 # for p in reversed(primeList): # l = subsetSum(primeList, p) # if len(l) > longest: # longest = len(l) # prime = p # print(prime) # Well it seems I completely misinterpreted the question and did something way more difficult than was intended prime = 0 longest = 0 for i in range(len(primeList)): s = 0 primes = [] for p in primeList[i:]: s += p primes.append(p) if s >= target: break if s in primeSet and len(primes) > longest: prime = s longest = len(primes) print(prime) if __name__ == "__main__": main()