Skip to content

Commit 6a6d168

Browse files
committed
improved prime numbers example
1 parent bbcf9aa commit 6a6d168

File tree

3 files changed

+99
-10
lines changed

3 files changed

+99
-10
lines changed

bibliography/bibliography.bib

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ @string { a_clinton_david
6767
@string { a_coghlan_alyssa = "Alyssa Coghlan" }
6868
@string { a_cormen_thomas_h = "Thomas H.\ Cormen" }
6969
@string { a_cornapeau_david = "David Cournapeau" }
70+
@string { a_crandall_richard = "Richard Crandall" }
7071
@string { a_crossley_john_newsome = "John Newsome Crossley" }
7172
@string { a_cullen_christopher = "Christopher Cullen" }
7273
@string { a_d_alche_buc_florence = "Florence d'Alch{\'e}{-}Buc" }
@@ -202,13 +203,15 @@ @string { a_peterson_pearu
202203
@string { a_picus_matti = "Matti Picus" }
203204
@string { a_polat_ilhan = "Ilhan Polat" }
204205
@string { a_pollard_tom_j = "Tom J.\ Pollard" }
206+
@string { a_pomerance_carl = "Carl Pomerance" }
205207
@string { a_press_william_h = "William H.\ Press" }
206208
@string { a_prettenhofer_peter = "Peter Prettenhofer" }
207209
@string { a_quinter_ea = "E.\ A.\ Quintero" }
208210
@string { a_raison_martin = "Martin Raison" }
209211
@string { a_raschka_sebastian = "Sebastian Raschka" }
210212
@string { a_reddy_tyler = "Tyler Reddy" }
211213
@string { a_ribeiro_antonio_h = "Ant{\^o}nio H.\ Ribeiro" }
214+
@string { a_riesel_hans = "Hans Riesel" }
212215
@string { a_rivest_ronald_linn = "Ronald Linn Rivest" }
213216
@string { a_robertson_edmund_f = "Edmund F.\ Robertson" }
214217
@string { a_rodriguez_emily = "Emily Rodriguez" }
@@ -273,6 +276,7 @@ @string { a_warsaw_barry
273276
@string { a_weckesser_warren = "Warren Weckesser" }
274277
@string { a_weise_thomas = "Thomas Weise" }
275278
@string { a_weiss_ron = "Ron Weiss" }
279+
@string { a_weisstein_eric_w = "Eric Wolfgang Weisstein" }
276280
@string { a_wicke_martin = "Martin Wicke" }
277281
@string { a_wiebe_mark = "Mark Wiebe" }
278282
@string { a_wieser_eric = "Eric Wieser" }
@@ -314,10 +318,12 @@ @string { l_uk_oxford
314318
@string { l_uk_st_andrews = "{{St~Andrews}, {Scotland}, {UK}}" }
315319
@string { l_usa_beaverton = "{{Beaverton}, {OR}, {USA}}" }
316320
@string { l_usa_berkeley = "{{Berkeley}, {CA}, {USA}}" }
321+
@string { l_use_boston = "{{Boston}, {MA}, {USA}}" }
317322
@string { l_usa_boca_raton = "{{Boca Raton}, {FL}, {USA}}" }
318323
@string { l_usa_catonsville = "{{Catonsville}, {MD}, {USA}}" }
319324
@string { l_usa_cambridge = "{{Cambridge}, {MA}, {USA}}" }
320325
@string { l_usa_centennial = "{{Centennial}, {CO}, {USA}}" }
326+
@string { l_usa_champaign = "{{Champaign}, {IL}, {USA}}" }
321327
@string { l_usa_columbia = "{{Columbia}, {SC}, {USA}}" }
322328
@string { l_usa_hoboken = "{{Hoboken}, {NJ}, {USA}}" }
323329
@string { l_usa_ithaca = "{{Ithaca}, {NY}, {USA}}" }
@@ -350,6 +356,7 @@ @string { p_apress
350356
@string { p_asa = "{American Standards Association Incorporated}" }
351357
@string { p_astral = "Astral Software Inc." }
352358
@string { p_bell_labs = "{Bell Telephone Laboratories, Incorporated}" }
359+
@string { p_birkhauser_boston = "{Birkh{\"a}user}" }
353360
@string { p_bruhin_software = "{Bruhin Software}" }
354361
@string { p_cambridge_uni_press_ass = "{Cambridge University Press \& Assessment}" }
355362
@string { p_cnri = "{Corporation for National Research Initiatives~({CNRI})}" }
@@ -379,6 +386,7 @@ @string { p_python_software_foundation
379386
@string { p_springer = "{Springer}" }
380387
@string { p_springer_nature_limited = "{Springer Nature Limited}" }
381388
@string { p_springer_new_york = "{Springer New York}" }
389+
@string { p_springer_science_and_business = "{Springer Science+Business Media}" }
382390
@string { p_taylor_and_francis = "{Taylor and Francis Ltd.}" }
383391
@string { p_teubner_b_g = "{B.\ G.\ Teubner}" }
384392
@string { p_unicode_consortium = "{The Unicode Consortium}" }
@@ -390,6 +398,7 @@ @string { p_university_of_washington
390398
@string { p_usas = "{United States of America Standards Institute~{(USAS)}}" }
391399
@string { p_usenix = "{{USENIX} Association}" }
392400
@string { p_wiley_and_sons_ltd = "{John Wiley and Sons Ltd.}" }
401+
@string { p_wolfram_research = "{Wolfram Research, Inc.}" }
393402
394403
395404
%% publisher addresses
@@ -402,6 +411,7 @@ @string { pa_apress
402411
@string { pa_asa = l_usa_new_york }
403412
@string { pa_astral = l_usa_new_york }
404413
@string { pa_bell_labs = l_usa_new_york }
414+
@string { pa_birkhauser_boston = l_use_boston }
405415
@string { pa_bruhin_software = l_switzerland_winterthur }
406416
@string { pa_cambridge_uni_press_ass = l_uk_cambridge }
407417
@string { pa_cnri = l_usa_reston }
@@ -431,6 +441,7 @@ @string { pa_python_software_foundation
431441
@string { pa_springer_cham = l_switzerland_cham }
432442
@string { pa_springer_nature_limited = l_uk_london }
433443
@string { pa_springer_new_york = l_usa_new_york }
444+
@string { pa_springer_science_and_business = l_usa_new_york }
434445
@string { pa_taylor_and_francis = l_uk_london }
435446
@string { pa_teubner_b_g = l_germany_leipzig }
436447
@string { pa_unicode_consortium = l_usa_south_san_francisco }
@@ -442,6 +453,7 @@ @string { pa_university_of_washington
442453
@string { pa_usas = l_usa_new_york }
443454
@string { pa_usenix = l_usa_berkeley }
444455
@string { pa_wiley_and_sons_ltd = l_uk_chichester }
456+
@string { pa_wolfram_research = l_usa_champaign }
445457

446458

447459
%% conferences
@@ -620,6 +632,13 @@ @xdata{ser_lipics
620632
address = pa_leibniz_zentrum_fur_informatik
621633
}
622634

635+
@xdata{ser_pm,
636+
series = {Progress in Mathematics~{(PM)}},
637+
issn = {0743-1643},
638+
publisher = p_springer_science_and_business,
639+
address = pa_springer_science_and_business
640+
}
641+
623642
@xdata{ser_taocp,
624643
series = {The Art of Computer Programming},
625644
author = a_knuth_donald_ervin,
@@ -859,6 +878,17 @@ @book{CN2020ULB
859878
xdata = {ser_bs},
860879
}
861880

881+
@book{CP2005PNACP,
882+
author = a_crandall_richard # and # a_pomerance_carl,
883+
title = {Prime Numbers: A Computational Perspective},
884+
edition = {2},
885+
publisher = p_springer_new_york,
886+
address = pa_springer_new_york,
887+
date = {2005-08-04},
888+
isbn = {978-0-387-25282-7},
889+
doi = {10.1007/0-387-28979-8},
890+
}
891+
862892
@book{CR2003LH,
863893
author = a_oconnor_john_j # and # a_robertson_edmund_f,
864894
title = {Liu Hui},
@@ -1503,6 +1533,17 @@ @article{PVGMTGBPWDVPCBPD2011SMLIP
15031533
doi = {10.5555/1953048.2078195},
15041534
}
15051535

1536+
@book{R1994PNACMFF,
1537+
author = a_riesel_hans,
1538+
title = {Prime Numbers and Computer Methods for Factorization},
1539+
xdata = {ser_pm},
1540+
doi = {10.1007/978-1-4612-0251-6},
1541+
imprint = pa_birkhauser_boston # {:~} # p_birkhauser_boston,
1542+
isbn = {978-0-8176-3743-9},
1543+
date = {1994-10-01/2012-09-30},
1544+
edition = {2}
1545+
}
1546+
15061547
@inproceedings{R2023PTHATCPBNI,
15071548
author = a_roth_ori,
15081549
title = {\python\ Type Hints Are Turing Complete (Pearl/Brave New Idea)},
@@ -1703,6 +1744,23 @@ @inproceedings{VVH2018ELDOSAIOSPACSOTPE
17031744
crossref = {PROC2018ESECFSE},
17041745
}
17051746

1747+
@book{W2024MAWWR,
1748+
title = {{MathWorld} -- A {Wolfram} Web Resource},
1749+
author = a_weisstein_eric_w,
1750+
date = {2024-08-22},
1751+
publisher = p_wolfram_research,
1752+
address = pa_wolfram_research,
1753+
url = {https://mathworld.wolfram.com/},
1754+
urldate = {2024-09-24},
1755+
}
1756+
1757+
@inbook{W2024PN,
1758+
title = {Prime Number},
1759+
crossref = {W2024MAWWR},
1760+
url = {https://mathworld.wolfram.com/PrimeNumber.html},
1761+
urldate = {2024-09-24},
1762+
}
1763+
17061764
@inproceedings{WW2023RSDEWASSAA,
17071765
author = a_weise_thomas # and # a_wu_zhize,
17081766
title = {Replicable Self-Documenting Experiments with Arbitrary Search Spaces and Algorithms},

notation/math.sty

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,22 @@
33
%%%
44
\protected\gdef\mathSpace#1{\ensuremath{\mathbb{#1}}}%
55
%
6+
\newSymbol{naturalNumbersZ}{\ensuremath{\mathSpace{N}_0}}{N0}{%
7+
the set of the natural numbers \emph{including}~0, i.e., 0, 1, 2, 3, and so on. %
8+
It holds that~$\naturalNumbersZ\subset\integerNumbers$%
9+
}%
10+
\newSymbol{naturalNumbersO}{\ensuremath{\mathSpace{N}_1}}{N1}{%
11+
the set of the natural numbers \emph{excluding}~0, i.e., 1, 2, 3, 4, and so on. %
12+
It holds that~$\naturalNumbersO\subset\integerNumbers$}%
13+
%
14+
\newSymbol{integerNumbers}{\ensuremath{\mathSpace{Z}}}{Z}{%
15+
the set of the integers numbers including positive and negative numbers and~0, i.e., {\dots}, -3, -2, -1, 0, 1, 2, 3, {\dots}, and so on. %
16+
It holds that~$\integerNumbers\subset\realNumbers$.}%
17+
%
618
\newSymbol{realNumbers}{\mathSpace{R}}{R}{the set of the real numbers}%
7-
\newSymbol{realNumbersP}{\ensuremath{\mathSpace{R}^+}}{R+}{the set of the positive real numbers, i.e., $\mathSpace{R}^+=\{x\in\realNumbers:x>0\}$}%
8-
\newSymbol{integerNumbers}{\ensuremath{\mathSpace{Z}}}{Z}{the set of the integers numbers including positive and negative numbers and~0, i.e., {\dots}, -3, -2, -1, 0, 1, 2, 3, {\dots}, and so on}%
19+
%
20+
\newSymbol{realNumbersP}{\ensuremath{\mathSpace{R}^+}}{R+}{%
21+
the set of the positive real numbers, i.e., $\mathSpace{R}^+=\{x\in\realNumbers:x>0\}$}%
922
%
1023
\protected\gdef\intRange#1#2{\ensuremath{#1\pgls{intSetDots}#2}}%
1124
\newglossaryentry{intSetDots}{%

text/main/controlFlow/loops/loops.tex

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
Instead of doing this, we can put this into a loop, which reduces the lines of code from over~25 to about~10 in \cref{lst:loops:for_loop_pi_liu_hui}.
8383
The outputs in \cref{exec:variables:pi_liu_hui,exec:loops:for_loop_pi_liu_hui} are exactly the same.%
8484
%
85+
\FloatBarrier%
8586
\endhsection%
8687
%
8788
\hsection{The \texttt{continue} and \texttt{break} Statements}%
@@ -118,6 +119,7 @@
118119
This can be observed in the program output collected in \cref{exec:loops:for_loop_continue_break}.
119120
With \pythonilIdx{break} and \pythonilIdx{continue}, we now have two tools that can help us to either abort any loop prematurely or to abort the current iteration of the loop prematurely (and continue with the next one, if any), respectively.%
120121
%
122+
\FloatBarrier%
121123
\endhsection%
122124
%
123125
\hsection{Nesting Loops}%
@@ -126,9 +128,13 @@
126128
Computing a list of all primes from \intRange{2}{200} using nested \pythonilIdx{for} loops.}%
127129
%
128130
Like conditional statements, \pythonilIdx{for}~loops can be arbitrarily nested.
129-
Let us explore this by computing the list of all prime numbers less than~200 (in a very crude way) in \cref{lst:loops:for_loop_nested_primes}.
130-
131-
In this program, we want to store all of these prime numbers in the list\pythonIdx{list} \pythonil{primes}.
131+
Let us explore this by computing the list of all prime numbers less than~200 in \cref{lst:loops:for_loop_nested_primes}.%
132+
%
133+
\begin{definition}[Prime Number]%
134+
A prime number~$p\in\naturalNumbersO$ is a positive integer~$p>1$ that has no positive integer divisors other than~$1$ and~$p$ itself~\cite{W2024PN,CP2005PNACP,R1994PNACMFF}.%
135+
\end{definition}%
136+
%
137+
In our example program, we want to store all of these prime numbers in the list\pythonIdx{list} \pythonil{primes}.
132138
We know that \pythonil{2} is a prime number and the only even one, so we directly initialize \pythonil{primes = [2]}, i.e., we set \pythonil{primes} to initially be a list only containing the integer~\pythonil{2}.
133139
This will allow us to later on only consider the odd numbers in the range \intRange{3}{200}.
134140
Just out of interest, we will count the total number of divisions that we need to perform until we have the full list of primes in the variable~\pythonil{n_divisions}.%
@@ -147,11 +153,22 @@
147153
We will implement this idea with a nested inner loop.
148154
Since the loop variable \pythonil{candidate} will always be odd, only odd numbers can be potential divisors.
149155
Obviously, only integers greater than or equal to~\pythonil{3} and less than \pythonil{candidate} are potential divisors.
150-
We can therefore iterate a second, inner loop variable \pythonil{check} over \pythonil{range(3, candidate, 2)}\pythonIdx{range}.
151-
If \pythonil{candidate <= 3}, then this loop will never be executed because no number $3\leq\pythonil{check}<\pythonil{candidate}$ exists.
156+
We can therefore iterate a second, inner loop variable \pythonil{check} over \pythonil{range(3, isqrt(candidate) + 1, 2)}\pythonIdx{range}\pythonIdx{isqrt}.
157+
If \pythonil{candidate <= 3}, then this loop will never be executed because no number \pythonil{check} with $3\leq\pythonil{check}<\pythonil{candidate}$ exists.
152158
Then, \pythonil{is_prime} will remain \pythonil{True} and we will add \pythonil{candidate} to \pythonil{primes} further down the outer loop body.
153-
If \pythonil{candidate > 3}, then \pythonil{check} will go from \pythonil{3}, \dots, \pythonil{candidate - 2}.
154-
In order to find out whether \pythonil{check} is an even divisor of \pythonil{candidate}, we just need to compute the remainder of the division~$\pythonil{canddiate}/\pythonil{check}$.
159+
If \pythonil{candidate > 3}, then \pythonil{check} will go from $\pythonil{3}, \dots, \left\lfloor\sqrt{\pythonil{candidate}}\right\rfloor$.
160+
161+
We only need to explore whether \pythonil{check} is a divisor of \pythonil{candidate} if it is not bigger than $\sqrt{\pythonil{candidate}}$.
162+
If we had three integer numbers~$a$, $b$, and~$c$ such that $a=b*c$ and $b>\sqrt{a}$, then it must be that $c<\sqrt{a}$.
163+
Since $a=\sqrt{a}*\sqrt{a}$ holds by definition, it would be impossible that $a=b*c$ if both $b>\sqrt{a}$ and $c\geq\sqrt{a}$.
164+
Thus, if $b>\sqrt{a}$ was a divisor of $a$, then $c$ would also be a divisor of~$a$ that we would have found before reaching~$b$ in the loop since~$c<\sqrt{a}<b$.
165+
166+
Now, most integer numbers do not have integer square roots.
167+
Since integer divisors cannot have fractions anyway, it is sufficient for us to use $\left\lfloor\sqrt{\pythonil{candidate}}\right\rfloor$.
168+
In \python, such a \inQuotes{truncated} integer square root of an integer number~$\left\lfloor\sqrt{a}\right\rfloor$ can be computed using the \pythonilIdx{isqrt} function from the \pythonilIdx{math} module, which we \pythonilIdx{import} at the top of our program.
169+
170+
Anyway, back to our inner loop.
171+
In order to find out whether \pythonil{check} is an integer divisor of \pythonil{candidate}, we just need to compute the remainder of the division~$\pythonil{canddiate}/\pythonil{check}$.
155172
Back in \cref{sec:int:integerArithmetics} we learned the \pgls{modulodiv} operator \expandafter\pythonilIdx{\%}, which does exactly that.
156173
If \pythonil{candidate \% check} is~\pythonil{0}, then we can divide \pythonil{candidate} by \pythonil{check} without remainder.
157174
Then, \pythonil{candidate} is divisible by \pythonil{check} and cannot be a prime number.
@@ -161,8 +178,9 @@
161178

162179
After the inner loop, if \pythonil{is_prime} is still \pythonil{True}, we add \pythonil{candidate} to \pythonil{primes} by invoking the \pythonilIdx{append}\pythonIdx{list!append} method of the list.
163180
Once we have completed the outer loop as well, we print the number~\pythonil{n_divisions} of divisions we have performed, the number~\pythonil{len(primes)}\pythonIdx{len}\pythonIdx{list!len} of prime numbers we have discovered and, finally, the list~\pythonil{primes} itself.
164-
The output in \cref{exec:loops:for_loop_nested_primes} tells us that, after performing 2140 divisions, we could identify 46~prime numbers inside~\intRange{2}{200}.%
181+
The output in \cref{exec:loops:for_loop_nested_primes} tells us that, after performing 252~divisions, we could identify 46~prime numbers inside~\intRange{2}{200}.%
165182
%
183+
\FloatBarrier%
166184
\endhsection%
167185
%
168186
\endhsection%

0 commit comments

Comments
 (0)