Files
contests/projecteuler/050/main.py

117 lines
2.8 KiB
Python

'''
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()