This kata is inspired on the problem #50 of the Project Euler. 

The prime ``` 41```  is the result of the sum of many consecutive primes.

In fact, ``` 2 + 3 + 5 + 7 + 11 + 13 = 41 , (6 addens)   ``` 

Furthermore, the prime ``` 41```  is the prime below ``` 100 (val_max)```  that has the longest chain of consecutive prime addens.

The prime with longest chain of addens for ```val_max = 500``` is ```499``` with ```17``` addens. 

In fact:
```3+5+7+11+13+17+19+23+29+31+37+41+43+47+53+59+61= 499```

Find the function ```prime_maxlength_chain()```(primeMaxlengthChain() javascript), that receives an argument ```val_max```, the upper limit, all the found primes should be less than ```val_max``` and outputs this found prime.

Let's see some cases:
```python
prime_maxlength_chain(100) == [41]
prime_maxlength_chain(500) == [499]
```
If we have more than one prime with these features, the function should output an array with the found primes sorted.
```python
prime_maxlength_chain(499) == [379, 491]
```
Random Tests for `val_max` (`valMax`)
```
100 ≤ val_max ≤ 500.000
```
Enjoy it!

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Data structures

Mathematics

Starter code: def prime_maxlength_chain(n):
	

Solutions:
LIMIT = 500000
sieve = [True] * (LIMIT // 2)
for n in range(3, int(LIMIT ** 0.5) + 1, 2):
	if sieve[n // 2]:
		sieve[n * n // 2::n] = [False] * ((LIMIT - n * n - 1) // 2 // n + 1)
PRIMES = [2] + [2 * i + 1 for i in range(1, LIMIT // 2) if sieve[i]]

def prime_maxlength_chain(val_max):
	if val_max < 5:
		return []
	found = []
	for n in range(2, 400):
		if sum(PRIMES[:n]) >= val_max:
			max_size = n
			break
	for size in range(max_size, 1, -1):
		if size % 2 == 0:
			n = sum(PRIMES[:size])
			if n < val_max and n in PRIMES:
				return [n]
		else:
			for start in range(1, max_size - size + 1):
				n = sum(PRIMES[start:start + size])
				if n < val_max and n in PRIMES:
					found.append(n)
			if found:
				return found


def is_prime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def prime_maxlength_chain(n):
	(summ, primes, res) = (0, [], [])
	for i in range(2, n):
		if is_prime(i):
			if summ + i < n:
				summ += i
				primes.append(i)
			elif summ + i - primes[0] < n:
				summ += i
				primes.append(i)
			else:
				break
	l = len(primes)
	for j in range(l, 0, -1):
		for k in range(l - j + 1):
			lst = primes[k:k + j]
			temp = sum(lst)
			if is_prime(temp):
				res.append(temp)
		if len(res) != 0:
			break
	return res


from itertools import accumulate
from bisect import bisect_left
import numpy as np
limit = 555555
sieve = np.ones(limit, dtype=bool)
sieve[0] = sieve[1] = 0
sieve[2 * 2::2] = 0
for i in range(3, int(len(sieve) ** 0.5) + 1, 2):
	if sieve[i]:
		sieve[i * i::i] = 0
primes = [i for (i, x) in enumerate(sieve) if x]
acc_primes = list(accumulate([0] + primes))
s_primes = set(primes)

def prime_maxlength_chain(n):
	limit = bisect_left(primes, n)
	(ans, max_len) = ([], 1)
	for l in range(limit):
		for r in range(l + max_len, limit + 1):
			t = acc_primes[r] - acc_primes[l]
			if t >= n:
				break
			if t in s_primes and r - l >= max_len:
				(ans, max_len) = ([t], r - l) if r - l > max_len else (ans + [t], max_len)
	return ans


limit = 500000
sieve = [0] * 2 + list(range(2, limit))
for i in range(2, limit):
	for j in range(i * i, limit, i):
		sieve[j] = 0
primes = [i for i in sieve if i]

def prime_maxlength_chain(n):
	req = [i for i in primes if i < n]
	P = set(req)
	D = {}
	found = []
	for (i, j) in enumerate(req):
		D[j] = [0, 0]
		for k in list(D):
			(o, p) = D[k]
			if o in P:
				found.append([o, p])
			if o + j > n:
				del D[k]
				continue
			D[k][0] += j
			D[k][1] += 1
	m = max(found, key=lambda x: x[1])[1]
	return [i[0] for i in found if i[1] == m]


def prime_maxlength_chain(n):
	p = [False, False] + [True] * (n - 1)
	for i in range(2, n + 1):
		if p[i]:
			for j in range(i * 2, n + 1, i):
				p[j] = False
	pn = [i for (i, b) in enumerate(p) if b]
	ps = set(pn)
	maxl = [0, []]
	for l in range(6, len(pn)):
		if sum(pn[:l]) >= n:
			break
		for i in range(len(pn) - l):
			s = sum(pn[i:i + l])
			if s >= n:
				break
			elif s in ps:
				if maxl[0] < l:
					maxl = [l, [s]]
				else:
					maxl[1].append(s)
	return maxl[1]


def prime_maxlength_chain(val_max):
	primes = []
	sieve = [1] * (val_max + 1)
	sieve[0] = 0
	sieve[1] = 0
	for i in range(2, val_max + 1):
		if sieve[i] == 0:
			continue
		for j in range(i * i, val_max + 1, i):
			sieve[j] = 0
	for i in range(val_max + 1):
		if sieve[i] == 1:
			primes.append(i)
	for j in range(400, -1, -1):
		answer = []
		acc = 0
		if len(primes) < j:
			continue
		for i in range(j):
			acc += primes[i]
		if acc <= val_max and sieve[acc] == 1:
			answer.append(acc)
		for i in range(j, len(primes)):
			acc += primes[i]
			acc -= primes[i - j]
			if acc >= val_max:
				break
			if acc <= val_max and sieve[acc] == 1:
				answer.append(acc)
		if len(answer) > 0:
			return answer


def sieve(n):
	n = n - 1
	primes = [True for i in range(n + 1)]
	result = []
	p = 2
	while p * p <= n:
		if primes[p]:
			for i in range(p * 2, n + 1, p):
				primes[i] = False
		p += 1
	for p in range(2, n + 1):
		if primes[p]:
			result.append(p)
	return result

def prime_maxlength_chain(n):
	prime_num = sieve(n)
	prime_sums = [[0, 2]]
	count_max = 0
	results = []
	if n == 0:
		return []
	(i, j) = (0, 0)
	while sum(prime_num[i:count_max + i + j]) < n:
		while sum(prime_num[i:count_max + i + j]) < n:
			count = len(prime_num[i:count_max + i + j])
			summe = sum(prime_num[i:count_max + i + j])
			if summe in prime_num:
				prime_sums.append([count, summe])
			j += 1
		if count_max <= prime_sums[-1][0]:
			count_max = prime_sums[-1][0]
		i += 1
		j = 0
	prime_sums.sort()
	for p in prime_sums:
		if p[0] == prime_sums[-1][0]:
			results.append(p[1])
	return results


import numpy

def primesto(n):
	sieve = numpy.ones(n // 2, dtype=numpy.bool)
	for i in range(3, int(n ** 0.5) + 1, 2):
		if sieve[i // 2]:
			sieve[i * i // 2::i] = False
	return [2] + list(2 * numpy.nonzero(sieve)[0][1:] + 1)

def cum_sum_500k():
	return numpy.array([0] + primesto(500000)).cumsum()

def circular_list():
	p = primesto(500000)
	c = cum_sum_500k()
	l = []
	s = 1
	for i in range(400):
		for j in range(0, i - s + 1):
			x = c[i] - c[j]
			if x in p:
				if i - j > s:
					s = i - j
				l += [[x, i - j]]
	l.sort()
	return l

def prime_maxlength_chain(n):
	if prime_maxlength_chain.cl == []:
		prime_maxlength_chain.cl = circular_list()
	cl = prime_maxlength_chain.cl
	for i in range(len(cl)):
		idx = 0
		if cl[i][0] >= n:
			idx = i - 1
			break
	l = []
	for i in range(idx, 1, -1):
		if cl[i][1] == cl[idx][1]:
			l += [cl[i][0]]
		else:
			break
	l.sort()
	return l
prime_maxlength_chain.cl = [[2, 1], [3, 1], [5, 2], [17, 4], [41, 6], [127, 9], [197, 12], [281, 14], [379, 15], [491, 15], [499, 17], [563, 17], [857, 19], [953, 21], [1151, 23], [1259, 25], [1361, 25], [1583, 27], [1823, 27], [2069, 27], [2099, 29], [2399, 31], [2417, 33], [2579, 35], [2897, 35], [2909, 37], [3803, 39], [3821, 41], [4217, 43], [4421, 43], [4651, 45], [4871, 45], [5107, 47], [5333, 47], [5813, 49], [6053, 49], [6079, 53], [6599, 55], [7699, 60], [8273, 61], [8893, 64], [9521, 65], [10181, 65], [10859, 65], [11597, 71], [12329, 71], [12713, 73], [13099, 75], [13877, 75], [14669, 75], [15527, 79], [16823, 81], [18131, 81], [19013, 81], [21407, 85], [22037, 95], [22039, 96], [24133, 100], [25237, 102], [28087, 103], [28099, 105], [28687, 105], [28697, 108], [31729, 111], [32353, 114], [33623, 115], [34913, 117], [36217, 117], [36871, 117], [37561, 122], [38921, 124], [41017, 125], [42451, 125], [42463, 127], [43201, 130], [44683, 132], [47711, 133], [49253, 133], [49279, 137], [52517, 141], [54167, 143], [55837, 146], [61027, 152], [64613, 155], [66463, 158], [70241, 162], [76099, 163], [78121, 165], [78139, 167], [79151, 167], [81203, 169], [84313, 171], [86453, 178], [92951, 183], [101999, 191], [102001, 192], [109147, 198], [115279, 201], [116531, 203], [116533, 204], [119069, 206], [121631, 208], [129419, 214], [132059, 216], [137477, 217], [138863, 219], [141671, 221], [147347, 221], [148817, 225], [153137, 225], [154579, 225], [157489, 225], [157561, 229], [157579, 231], [162007, 231], [163483, 231], [164963, 231], [164999, 233], [166541, 237], [171131, 239], [172687, 241], [175781, 241], [178889, 241], [182009, 241], [182099, 247], [182107, 249], [198197, 251], [199831, 251], [201599, 257], [203279, 259], [204979, 261], [210053, 261], [213461, 261], [213533, 267], [215261, 267], [218749, 269], [222269, 273], [225821, 273], [225829, 275], [240353, 279], [240371, 281], [240379, 283], [242243, 283], [244109, 283], [251609, 285], [255443, 291], [257353, 291], [263171, 296], [269069, 297], [281023, 299], [283079, 305], [287137, 308], [303643, 309], [303691, 313], [305783, 313], [310019, 317], [314267, 317], [318557, 321], [324991, 321], [325009, 323], [325019, 326], [329401, 328], [333821, 330], [338279, 332], [342761, 334], [351811, 335], [354097, 337], [356387, 339], [360977, 341], [360979, 342], [370261, 343], [372607, 345], [379667, 350], [393961, 356], [398771, 358], [408479, 359], [423257, 361], [423287, 363], [425819, 365], [428339, 365], [433421, 367], [433439, 369], [438521, 369], [441101, 373], [448859, 375], [448867, 377], [477809, 377], [478001, 387], [483377, 389], [496877, 391], [499607, 393]]