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
Copy file name to clipboardExpand all lines: src/algebra/euclid-algorithm.md
+7-22Lines changed: 7 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,9 @@ The algorithm was first described in Euclid's "Elements" (circa 300 BC), but it
14
14
15
15
## Algorithm
16
16
17
-
The algorithm is extremely simple:
17
+
Originally, Euclidean algorithm was formulated as follows: subtract smaller number from the larger one until one of the numbers is zero. Indeed, if $g$ divides $a$ and $b$, it also divides $a-b$. On the other hand, if $g$ divides $a-b$ and $b$, then it also divides $a = b + (a-b)$, which means that the sets of divisors of $\{a, b\}$ and $\{b,a-b\}$ coincide.
18
+
19
+
Note that $a$ remains the larger number until $b$ is subtracted from it at least $\left\lfloor\frac{a}{b}\right\rfloor$ times. Therefore, to speed things up, $a-b$ is substituted with $a-\left\lfloor\frac{a}{b}\right\rfloor b = a \bmod b$. Then the algorithm can be formulated in an extremely simple way:
18
20
19
21
$$\gcd(a, b) = \begin{cases}a,&\text{if }b = 0 \\\\ \gcd(b, a \bmod b),&\text{otherwise.}\end{cases}$$
20
22
@@ -49,26 +51,7 @@ int gcd (int a, int b) {
49
51
}
50
52
```
51
53
52
-
## Correctness Proof
53
-
54
-
First, notice that in each iteration of the Euclidean algorithm the second argument strictly decreases, therefore (since the arguments are always non-negative) the algorithm will always terminate.
55
-
56
-
For the proof of correctness, we need to show that $\gcd(a, b) = \gcd(b, a \bmod b)$ for all $a \geq 0$, $b > 0$.
57
-
58
-
We will show that the value on the left side of the equation divides the value on the right side and vice versa. Obviously, this would mean that the left and right sides are equal, which will prove Euclid's algorithm.
59
-
60
-
Let $d = \gcd(a, b)$. Then by definition $d\mid a$ and $d\mid b$.
61
-
62
-
Now let's represent the remainder of the division of $a$ by $b$ as follows:
63
-
$$a \bmod b = a - b \cdot \Bigl\lfloor\dfrac{a}{b}\Bigr\rfloor$$
64
-
65
-
From this it follows that $d \mid (a \bmod b)$, which means we have the system of divisibilities:
66
-
$$\begin{cases}d \mid b,\\\\ d \mid (a \mod b)\end{cases}$$
67
-
68
-
Now we use the fact that for any three numbers $p$, $q$, $r$, if $p\mid q$ and $p\mid r$ then $p\mid \gcd(q, r)$. In our case, we get:
69
-
$$d = \gcd(a, b) \mid \gcd(b, a \mod b)$$
70
-
71
-
Thus we have shown that the left side of the original equation divides the right. The second half of the proof is similar.
54
+
Note that since C++17, `gcd` is implement as a [standard function](https://en.cppreference.com/w/cpp/numeric/gcd) in C++.
72
55
73
56
## Time Complexity
74
57
@@ -80,6 +63,8 @@ Moreover, it is possible to show that the upper bound of this theorem is optimal
80
63
81
64
Given that Fibonacci numbers grow exponentially, we get that the Euclidean algorithm works in $O(\log \min(a, b))$.
82
65
66
+
Another way to estimate the complexity is to notice that $a \bmod b$ for the case $a \geq b$ is at least $2$ times smaller than $a$, so the larger number is reduced at least in half on each iteration of the algorithm.
67
+
83
68
## Least common multiple
84
69
85
70
Calculating the least common multiple (commonly denoted **LCM**) can be reduced to calculating the GCD with the following simple formula:
@@ -107,7 +92,7 @@ It's based on a few properties:
107
92
108
93
- If both numbers are even, then we can factor out a two of both and compute the GCD of the remaining numbers: $\gcd(2a, 2b) = 2 \gcd(a, b)$.
109
94
- If one of the numbers is even and the other one is odd, then we can remove the factor 2 from the even one: $\gcd(2a, b) = \gcd(a, b)$ if $b$ is odd.
110
-
- If both numbers are odd, then subtracting one number of the other one will not change the GCD: $\gcd(a, b) = \gcd(b, a-b)$ (this can be proven in the same way as the correctness proof of the normal algorithm)
95
+
- If both numbers are odd, then subtracting one number of the other one will not change the GCD: $\gcd(a, b) = \gcd(b, a-b)$
111
96
112
97
Using only these properties, and some fast bitwise functions from GCC, we can implement a fast version:
0 commit comments