Last active
August 30, 2020 16:10
-
-
Save anandology/90c4a7dadbb650cd7d5c4645b94e5b30 to your computer and use it in GitHub Desktop.
Python is infinitely beautiful! -- https://anandology.com/blog/python-is-infintely-beautiful/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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