diff --git a/50/main.py b/50/main.py new file mode 100644 index 0000000..29923ae --- /dev/null +++ b/50/main.py @@ -0,0 +1,117 @@ +''' +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() \ No newline at end of file