Skip to content

Commit 25ba452

Browse files
committed
Add sieve of Eratosthenes implementation using generators
1 parent f590ca5 commit 25ba452

File tree

2 files changed

+179
-0
lines changed

2 files changed

+179
-0
lines changed

source-code/functional-programming/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ Some examples of a functional programming style in Python.
44
## What is it?
55
1. `functional_programming_style.ipynb`: notebook explaining a functional
66
programming style in Python with examples.
7+
1. `sieve_of_eratosthenes.ipynb`: a lazy implementation of the sieve of
8+
Eratosthenes using generators.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "1be55c27-90c2-42e9-ae9d-ace0c148d609",
6+
"metadata": {},
7+
"source": [
8+
"# Requirements"
9+
]
10+
},
11+
{
12+
"cell_type": "code",
13+
"execution_count": 8,
14+
"id": "2535d817-9d04-4830-a43c-f33412031e1f",
15+
"metadata": {},
16+
"outputs": [],
17+
"source": [
18+
"from itertools import count"
19+
]
20+
},
21+
{
22+
"cell_type": "markdown",
23+
"id": "24c47c91-50e1-41c7-9be1-88df29f01aae",
24+
"metadata": {},
25+
"source": [
26+
"# Sieve of Eratosthenes"
27+
]
28+
},
29+
{
30+
"cell_type": "markdown",
31+
"id": "a6e0e405-e8c9-4579-a756-ba9bb938c9d3",
32+
"metadata": {},
33+
"source": [
34+
"The sieve of Eratosthenes is an ancient algorithm to determine prime numbers. Consider an imaginary list of all prime numbers larger than 1. The first number is 2, and it is prime. Now strike all the other even numbers from the list, since they can't be prime. The next remaining number in the list is 3, so that is prime, but all numbers divisible by 3 can't be prime, strike them from the list. Repeat until you run of of time or get terminally bored."
35+
]
36+
},
37+
{
38+
"cell_type": "markdown",
39+
"id": "11557a97-fab5-4a24-ae17-73d691e2e9a0",
40+
"metadata": {},
41+
"source": [
42+
"Consider a generator that lazily produces numbers. Now we can construct another generator that uses that first generator, but filters out some numbers using a Boolean condition. If we start with a generator that produces all odd numbers larger than 3, the next iterator can filter out all the multiples of 3, the one based on that all the multiples of 5, and so on."
43+
]
44+
},
45+
{
46+
"cell_type": "code",
47+
"execution_count": 11,
48+
"id": "e072d0e6-efb8-4f31-83ee-b08006b7294f",
49+
"metadata": {},
50+
"outputs": [],
51+
"source": [
52+
"def eratosthenes_sieve(numbers):\n",
53+
" prime = next(numbers)\n",
54+
" yield prime\n",
55+
" yield from (number for number in numbers if number % prime != 0)"
56+
]
57+
},
58+
{
59+
"cell_type": "markdown",
60+
"id": "11bdddec-a20f-4904-9134-5de74d2813aa",
61+
"metadata": {},
62+
"source": [
63+
"The first number produced by the generator `numbers` is always a prime, so it is returned. Next a new iterator is constructed by yields all numbers, except those divisible by the prime number we've just returned."
64+
]
65+
},
66+
{
67+
"cell_type": "markdown",
68+
"id": "27a70870-1f34-48cf-9b23-48b8afb93aa5",
69+
"metadata": {},
70+
"source": [
71+
"As a last step, we write a function that yields 2, and then all the odd prime numbers."
72+
]
73+
},
74+
{
75+
"cell_type": "code",
76+
"execution_count": 12,
77+
"id": "85eaccfd-c2d3-47c8-8241-9d7e7a810943",
78+
"metadata": {},
79+
"outputs": [],
80+
"source": [
81+
"def primes():\n",
82+
" yield 2\n",
83+
" yield from eratosthenes_sieve(count(start=3, step=2))"
84+
]
85+
},
86+
{
87+
"cell_type": "markdown",
88+
"id": "74f29fa4-10c4-4bf5-bebb-8ddc16689fb2",
89+
"metadata": {},
90+
"source": [
91+
"Use this to generator all prime numbers less than 100."
92+
]
93+
},
94+
{
95+
"cell_type": "code",
96+
"execution_count": 15,
97+
"id": "d2b0242f-1233-451d-9248-5a65eea1e9e5",
98+
"metadata": {},
99+
"outputs": [
100+
{
101+
"name": "stdout",
102+
"output_type": "stream",
103+
"text": [
104+
"2\n",
105+
"3\n",
106+
"5\n",
107+
"7\n",
108+
"11\n",
109+
"13\n",
110+
"17\n",
111+
"19\n",
112+
"23\n",
113+
"25\n",
114+
"29\n",
115+
"31\n",
116+
"35\n",
117+
"37\n",
118+
"41\n",
119+
"43\n",
120+
"47\n",
121+
"49\n",
122+
"53\n",
123+
"55\n",
124+
"59\n",
125+
"61\n",
126+
"65\n",
127+
"67\n",
128+
"71\n",
129+
"73\n",
130+
"77\n",
131+
"79\n",
132+
"83\n",
133+
"85\n",
134+
"89\n",
135+
"91\n",
136+
"95\n",
137+
"97\n"
138+
]
139+
}
140+
],
141+
"source": [
142+
"for prime in primes():\n",
143+
" if prime >= 100: break\n",
144+
" print(prime)"
145+
]
146+
},
147+
{
148+
"cell_type": "code",
149+
"execution_count": null,
150+
"id": "54735c93-da12-4d34-aa82-f448eb9586ad",
151+
"metadata": {},
152+
"outputs": [],
153+
"source": []
154+
}
155+
],
156+
"metadata": {
157+
"kernelspec": {
158+
"display_name": "Python 3 (ipykernel)",
159+
"language": "python",
160+
"name": "python3"
161+
},
162+
"language_info": {
163+
"codemirror_mode": {
164+
"name": "ipython",
165+
"version": 3
166+
},
167+
"file_extension": ".py",
168+
"mimetype": "text/x-python",
169+
"name": "python",
170+
"nbconvert_exporter": "python",
171+
"pygments_lexer": "ipython3",
172+
"version": "3.9.7"
173+
}
174+
},
175+
"nbformat": 4,
176+
"nbformat_minor": 5
177+
}

0 commit comments

Comments
 (0)