You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
+
%
6
18
\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}%
Copy file name to clipboardExpand all lines: text/main/controlFlow/loops/loops.tex
+26-8Lines changed: 26 additions & 8 deletions
Original file line number
Diff line number
Diff line change
@@ -82,6 +82,7 @@
82
82
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}.
83
83
The outputs in \cref{exec:variables:pi_liu_hui,exec:loops:for_loop_pi_liu_hui} are exactly the same.%
84
84
%
85
+
\FloatBarrier%
85
86
\endhsection%
86
87
%
87
88
\hsection{The \texttt{continue} and \texttt{break} Statements}%
@@ -118,6 +119,7 @@
118
119
This can be observed in the program output collected in \cref{exec:loops:for_loop_continue_break}.
119
120
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.%
120
121
%
122
+
\FloatBarrier%
121
123
\endhsection%
122
124
%
123
125
\hsection{Nesting Loops}%
@@ -126,9 +128,13 @@
126
128
Computing a list of all primes from \intRange{2}{200} using nested \pythonilIdx{for} loops.}%
127
129
%
128
130
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}.
132
138
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}.
133
139
This will allow us to later on only consider the odd numbers in the range \intRange{3}{200}.
134
140
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 @@
147
153
We will implement this idea with a nested inner loop.
148
154
Since the loop variable \pythonil{candidate} will always be odd, only odd numbers can be potential divisors.
149
155
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.
152
158
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}$.
155
172
Back in \cref{sec:int:integerArithmetics} we learned the \pgls{modulodiv} operator \expandafter\pythonilIdx{\%}, which does exactly that.
156
173
If \pythonil{candidate \% check} is~\pythonil{0}, then we can divide \pythonil{candidate} by \pythonil{check} without remainder.
157
174
Then, \pythonil{candidate} is divisible by \pythonil{check} and cannot be a prime number.
@@ -161,8 +178,9 @@
161
178
162
179
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.
163
180
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}.%
0 commit comments