RosettaCodeData/Task/Summarize-primes/Python/summarize-primes.py

75 lines
1.5 KiB
Python

'''Prime sums of primes up to 1000'''
from itertools import accumulate, chain, takewhile
# primeSums :: [(Int, (Int, Int))]
def primeSums():
'''Non finite stream of enumerated tuples,
in which the first value is a prime,
and the second the sum of that prime and all
preceding primes.
'''
return (
x for x in enumerate(
accumulate(
chain([(0, 0)], primes()),
lambda a, p: (p, p + a[1])
)
) if isPrime(x[1][1])
)
# ------------------------- TEST -------------------------
# main :: IO ()
def main():
'''Prime sums of primes below 1000'''
for x in takewhile(
lambda t: 1000 > t[1][0],
primeSums()
):
print(f'{x[0]} -> {x[1][1]}')
# ----------------------- GENERIC ------------------------
# isPrime :: Int -> Bool
def isPrime(n):
'''True if n is prime.'''
if n in (2, 3):
return True
if 2 > n or 0 == n % 2:
return False
if 9 > n:
return True
if 0 == n % 3:
return False
def p(x):
return 0 == n % x or 0 == n % (2 + x)
return not any(map(p, range(5, 1 + int(n ** 0.5), 6)))
# primes :: [Int]
def primes():
''' Non finite sequence of prime numbers.
'''
n = 2
dct = {}
while True:
if n in dct:
for p in dct[n]:
dct.setdefault(n + p, []).append(p)
del dct[n]
else:
yield n
dct[n * n] = [n]
n = 1 + n
# MAIN ---
if __name__ == '__main__':
main()