Skip to content
TAOCP Companion

Euclid's Algorithm

Once you've stepped through Euclid's algorithm by hand, you may want to see a few more examples without the tedious calculations. Feel free to enter whatever values you want into the first row to see it in action:

mnr
119
54411968
1196851
685117
51170

Implementation

export function euclids_algorithm(m: number, n: number) {
  while (true) {
    const r: number = m % n // E1
    if (r == 0) return n // E2

    // E3
    m = n
    n = r
  }
}

Algorithm Structure

Algorithm F (Factorial). Given a positive integer n, find the factorial of n, that is, the product of all numbers 1,2,…,n.

  • F1. [Initialize f.] Set f←n.
  • F2. [Is it 1?] If n=1, the algorithm terminates; f is the answer.
  • F3. [Reduce.] Set n←n−1, f←f⋅n, and go back to step F2.

        flowchart LR
        accTitle: Flowchart of Algorithm F, Factorial
        accDescr: Start leads to F1, Initialize f. F1 leads to F2, is it 1. If no, F2 leads to F3, Reduce, which loops back to F2. If yes, F2 leads to Result.
        F1[F1. Initialize $$f$$.]
        F2[F2. Is it 1?]
        F3[F3. Reduce.]
        Start --> F1 --> F2 -- No --> F3 --> F2
        F2 -- Yes --> Result
        

Notation Reference

Algorithm F
Reference to an algorithm within the current section.
Algorithm 1.1E
Reference to an algorithm in a different section. For algorithms written on this site (like Algorithm F above) they will be referenced as W1.1F.
x←210
The ← assigns the result of an expression to a variable. In this case 1024 is assigned to the variable x.
x=y
Check if x is equal to y.
x↔y
Swap the values of x and y.
x←y←34
Assign variables x and y to the result of the expression, in this case 81.
If condition, do something
Perform "something" only if "condition" is true.
Indicates the end of the algorithm.
a[i]
The ith element of array a.
m[i,j]
The jth element of the ith array in the multi-dimensional array m.

Algorithm Feature Reference

Finiteness
An algorithm eventually terminates.
Definiteness
Each step of an algorithm contains no ambiguity.
Input
An algorithm takes zero or more inputs and defines its constraints.
Output
An algorithm has at least one resulting value which relates to the input.
Effectiveness
Operations of an algorithm are simple enough that they can be worked out by hand.

Algorithm E Correctness Proof Explanation

Since E3 changes the values of m and n, Knuth's goal is to demonstrate that the divisors of m and n are the same as the divisors for n and r. If this is accomplished, then of course the greatest value in that set will remain the same.

The typical strategy when proving equivalence of sets, say A and B is to demonstrate that A is a subset of B (A⊆B) and B⊆A. Demonstrating that one set is a subset of another involves taking a value in the smaller set (x∈A) and showing x∈B. For convenience, we'll define A and B as follows:

A
The set of divisors of m and n.
B
The set of divisors of n and r.

When Knuth points out that m−qn=r demonstrates that if a number divides both m and n it must therefore divide r, he is implicitly stating that A⊆B. Similarly, qn+r=m implies that B⊆A.

So because A=B, the set of divisors for m and n is the same as the set of divisors for n and r. Therefore, the largest divisor remains the same after step E3 is applied.

Worked Example of T3

Here are the operations involved in calculating the individual values for m:

m=1
  1. r←1
  2. r←0
m=2
  1. r←2
  2. r←1
  3. r←0
m=3
  1. r←0
T3=2+3+13=2

Explanation of Set Theory Grounding

To understand the set theory grounding, consider step E3. The information delivered to the step, along with the step number itself, form a packet of information describing the state of the machine executing the algorithm at that point:

mnrStep
544119683

This state is one element of Q. When f is applied to this state, a new state (also in Q) is produced:

mnrStep
11968681

Every combination of values for each of these steps forms additional elements of the set Q. Also included in Q are the members of I, which are bare pairs of m and n:

 mnrStep
i119544  
f(i)11954401

Because E2 can branch depending on the value of r, the output from that step has two separate forms:

 mnrStep
s1544119682
f(s1)544119683
s2511702
f(s2) 17  

Notice how information is stripped from f(s2), this is because it's the result and therefore a member of Ω. Because the algorithm is complete, f(f(s2))=f(s2).

Let us look again at the example worked in the book of (119,544), applying f repeatedly eventually leads to the output (17). Alongside each step, I've included the applicable portion of the equation Knuth provides.

 mnrStepEquation
x0119544  f((m,n))=(m,n,0,1)
x1=f(x0)11954401f((m,n,r,1))=(m,n,remainder of m divided by n,2)
x2=f(x1)1195441192f((m,n,r,2))=(n) if r=0, (m,n,r,3) otherwise
x3=f(x2)1195441193f((m,n,p,3))=(n,p,p,1)
x4=f(x3)5441191191f((m,n,r,1))=(m,n,remainder of m divided by n,2)
x5=f(x4)544119682f((m,n,r,2))=(n) if r=0, (m,n,r,3) otherwise
x6=f(x5)544119683f((m,n,p,3))=(n,p,p,1)
x7=f(x6)11968681f((m,n,r,1))=(m,n,remainder of m divided by n,2)
x8=f(x7)11968512f((m,n,r,2))=(n) if r=0, (m,n,r,3) otherwise
x9=f(x8)11968513f((m,n,p,3))=(n,p,p,1)
x10=f(x9)6851511f((m,n,r,1))=(m,n,remainder of m divided by n,2)
x11=f(x10)6851172f((m,n,r,2))=(n) if r=0, (m,n,r,3) otherwise
x12=f(x11)6851173f((m,n,p,3))=(n,p,p,1)
x13=f(x12)5117171f((m,n,r,1))=(m,n,remainder of m divided by n,2)
x14=f(x13)511702f((m,n,r,2))=(n) if r=0, (m,n,r,3) otherwise
x15=f(x14) 17   

This sequence x0,x1,…,x15 is collectively referred to as a computational sequence, with this particular example defined by (119,544). This one terminates in 15 steps because step 15 is the first step where a member of Ω is encountered.

For this mathematical model to be an algorithm, it must meet the five criteria outlined earlier in the section. As mathematical equations, they are by their nature definite, and the sets I and Ω ensure that there is iput and output. Finiteness is an additional constraint: all possible inputs must define computational sequences which terminate in a finite number of steps.

Effectiveness must also be achieved via additional constraints, but this can be accomplished by a number of different approaches. The discussion around A∗ is one example of this, constraining the expression of algorithms to mutating sequences of letters, which of course can be written down and therefore worked by hand.

Using A∗

Let's look at how to implement addition with the framework Knuth set forth to understand how it works. If we want to represent 3+5, the input could be aaabbbbb or a3b5. Here is the process we want to create:

a3b5a4b4a5b3a6b2a7b1a8

Transformations only occur when θj matches a part of the string, so in each step we want a b to transform into an a. To accomplish this, we can define θ0=b and ϕ0=a. This should be applied repeatedly until there are no more bs, so b0=0 will repeat the rule until θ0 no longer matches. Once all of those have been replaced, we need to move on to a new rule so a0=1, but we have the desired result so N=1.

Now consider multiplication, which is a little more complicated to model. To begin, we want to take a b and add a new value c into the mix for each a:

a3b5a2bacb4ab(ac)2b4b(ac)3b4

This can be done with θ0=ab, ϕ0=bac, b0=0 and a0=1. The c value is where we'll accumulate the result, so now that we're done with the leading b it can be discarded with θ1=ba, ϕ1=a, b1=2. We'll defer definition of a1 for the moment, as once there are no more ba values it's time to move to a new stage in the algorithm. Here is what we have at this point:

(ac)3b4

For j=0 to apply successfuly to the next b, though, the a values must all be adjacent to the leftmost b. So θ2=ac, ϕ2=ca and b2=2. With that it's possible to evaluate j=0 again, so a2=0.

c3a3b4c3b(ac)3b3c3(ac)3b3c6a3b3

Applying this process repeatedly will eventually reach c15a3, which means that θ1 does not apply and so a1=3. This step eliminates all values of a with θ3=a, ϕ3=empty, b3=3 and a3=4. We'll consider strings exclusively containing c as the output, so N=4.

Here is a tool to explore this more fully:

jθjϕjbjajRemove
0
1
2
3

N= 4

Enter a string below to watch the algorithm above apply to it, one stage at a time:

 Stringj
a3b50
4bacacacb41
acacacb42
c3a3b40
16c3bacacacb31
c3acacacb32
c6a3b30
28c6bacacacb21
c6acacacb22
c9a3b20
40c9bacacacb1
c9acacacb2
c12a3b0
52c12bacacac1
c12acacac2
60c15a30
61c15a31
c15a33
66c15 

Exercise and Answer Clarifications

3. It's unclear from the problem statement that assignment isn't entirely disallowed. So even though m←n is disallowed, expressions like "Divide m by n and let m be the remainder" still appears in the solution.

6. This is asking you to replicate the calculation for each possible value of m, not apply the equation provided for the nature of Tn.