Skip to content

Instantly share code, notes, and snippets.

@anandology
Last active August 30, 2020 16:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anandology/90c4a7dadbb650cd7d5c4645b94e5b30 to your computer and use it in GitHub Desktop.
Save anandology/90c4a7dadbb650cd7d5c4645b94e5b30 to your computer and use it in GitHub Desktop.
"""Python is infinitely beautiful!
This program is a response to the post "Infinite work is less work" by
Damian Conway[1].
This program demonstrates how infinity can be handled elegantly in
Python!
THE PROBLEM:
Write a script to generate first 10 strong and weak prime numbers.
A prime p[n] is "strong" if it's larger than the average of its two
neighbouring primes (i.e. p[n] > (p[n-1]+p[n+1])/2). A prime is "weak" if
it's smaller than the average of its two neighbours.
[1]: http://blogs.perl.org/users/damian_conway/2019/07/infinite-work-is-less-work.html
"""
import itertools
import sys
def is_prime(p):
"""Prime or not prime
"""
# take numbers from 2...sqrt(p)
numbers = itertools.takewhile(lambda n: n*n<=p, range(2, p))
return not any(p%n==0 for n in numbers)
def integers(start=1):
"""Generates infinite integers from a starting number.
"""
while True:
yield start
start += 1
def primes():
"""Generates infinite prime numbers.
Yes, really!
"""
return (n for n in integers(start=2) if is_prime(n))
def triplets(seq):
"""Returns the consecutive triplets from the given sequence.
>>> for a, b, c in triplets([1, 2, 3, 4, 5]):
... print(a, b, c)
...
1 2 3
2 3 4
3 4 5
"""
seq = iter(seq)
a = next(seq)
b = next(seq)
c = next(seq)
while True:
yield a, b, c
a, b, c = b, c, next(seq)
def take(n, seq):
"""Returns an iterator over the first n elements from the seq.
>>> list(take(5, primes()))
[2, 3, 5, 7, 11]
"""
return (x for x, _ in zip(seq, range(n)))
def main():
# how many primes to print?
if len(sys.argv) > 1:
n = int(sys.argv[1])
else:
n = 10
# generate strong and weak primes
strong_primes = (b for a, b, c in triplets(primes()) if b+b > a+c)
weak_primes = (b for a, b, c in triplets(primes()) if b+b < a+c)
# print n strong and weak primes
print("STRONG\tWEAK")
for sp, wp in take(n, zip(strong_primes, weak_primes)):
print("{:6d}\t{:4d}".format(sp, wp))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment