Search code examples
algorithmgreatest-common-divisorknuthtaocp

Knuth the art of computer programming ex 1.1.8


I can't figure out what Knuth meant in his instructions for an exercise 8 from Chapter 1.1.

The task is to make an efficient gcd algorithm of two positive integers m and n using his notation theta[j], phi[j], b[j] and a[j] where theta and phi are strings and a and b - positive integers which represent computational steps in this case.

Let an input be the string of the form a^mb^n.

An excellent explanation of Knuth's algorithm is given by schnaader here.

My question is how this may be connected with the direction given in the exercise to use his Algorithm E given in the book with original r (remainder) substituted by |m-n| and n substituted by min(m,n).


Solution

  • When Knuth says "Let the input be represented by the string a^mb^n", what he means is that the input should take the form of m number of as and n number of bs. So the input f((m,n)) where m = 3 and n = 2 would be represented by the string aaabb.

    Take a moment to look back at his equation 3 in that chapter, which represents a Markov algorithm. (below)

            f((σ,j)) = (σ,a_j)        if θ_j does not occur in σ
            f((σ,j)) = (αφ_jω,b_j)    if α is the shortest string for which σ = αθ_jω
            f((σ,N)) = (σ,N)
    

    So the idea is to define the sequence for each variable j, θ_j, φ_j, a_j & b_j. This way, using the above Markov's algorithm you can specify what happens to your input string, depending on the value of j.

    Now, to get onto your main question;

    My question is how this may be connected with the direction given in the excercise to use his Algorithm E given in the book with original r (remainder) substituted by |m-n| and n substituted by min(m,n).

    Essentially what Knuth is saying here, is that you can't do division with the above Markov's algorithm. So what's the closest thing to division? Well, essentially we can subtract the smaller number from the larger number until we're left with a remainder. For example;

    10 % 4 = 2 is the same as doing the following;

            10 - 4 = 6        Can we remove another 4? Yes. Do it again.
            6  - 4 = 2        Can we remove another 4? No. We have our remainder.
    

    And now we have our remainder. This is essentially what he wants you to do with our input string eg aaabb.

    If you read through Knuth's suggested answer in the back of the book and work through a couple of examples you will see that this is essentially what he is doing by removing the pairs ab and then adding a c until no more pairs ab exist. Taking the example I used at the top we get the string being manipulated as such aaabb, aab, caab, ca, cca, ccb, aab (then start again)

    Which is the same as r = m % n, m = n, n = r (then start again). The difference is of course that in the above we have used the modulus operator and division, but in the example above that we have only used subtraction.

    I hope this helps. I actually wrote a more in-depth analysis of Knuth's variation on a Markov algorithm on my blog. So if you're still feeling a little stuck have a read through the series.