Class 9 › Mathematics › Chapter
The World of Algorithms
What an algorithm is, the digit-by-digit addition algorithm, algorithms for the greatest common divisor (listing divisors, improvements, Euclid's subtraction method and Āryabhaṭa's division method), data structures, correctness and efficiency.
- Precise steps: an algorithm must be followed exactly as written. You should not need to guess or perform any action that is not stated.
- Basic steps: every algorithm is built from basic steps that we assume we can perform directly (for example, adding two single-digit numbers, or checking whether a smaller number divides a larger one).
- Repetition: the same step may be executed many times, for example, "for each $j$ in $1, 2, \dots, n$".
- Conditional steps: a step may happen only if a condition holds, for example, "add $j$ to the list only if $j$ divides $n$".
- Names for values: we give names to the values the algorithm keeps track of (such as carry, j or list-of-divisors). Without names, the steps would be clumsy to describe.
- Executing: running through an algorithm step by step is called executing it.
- A class of problems: an algorithm works for every input of its kind (any two numbers), not only for one instance.
- Three jobs for every algorithm: describe it precisely, justify that it gives the correct answer, and analyse how many steps it takes compared with the size of the input.
- Addition by counting: draw dots for the first number, then for the second, and count all the dots. This is how addition is defined, but it is very slow for large numbers.
- The faster way: write the numbers one below the other in the Indian place-value system, align the rightmost digits, and add column by column from right to left, passing a carry to the left.
- Why align from the right: digits in the same column have the same place value (units with units, tens with tens). Only quantities of the same place value can be added directly.
- Why the carry is never more than 1: the largest possible column total is $9 + 9 + 1 = 19$. Its units digit is written down and the carry is $1$.
- Why Step 5 is needed: if the leftmost column produces a carry of $1$ and Step 5 is missing, the answer loses its leading digit and is wrong. When the last carry is $0$, the algorithm gives the correct result even without Step 5.
- Carry condition: a column total of exactly $10$ also produces a carry. The rule is "$10$ or more", not only "more than $10$".
- Numbers of different lengths: the steps assume both numbers have a digit in every column. When one number runs out of digits, treat its missing digits as $0$ so the carry can keep moving left.
- Decimal fractions: align the decimal points (so equal place values line up), fill the shorter number with zeros on the right, add exactly as before, and place the decimal point in the answer directly below the other decimal points.
- Assumption: we already know how to add single-digit numbers without counting.
- Justification (grouping): every number is grouped into units, tens, hundreds, and so on. Adding the two numbers is the same as adding each group separately. Whenever a group reaches ten, those ten make one of the next larger group, so we carry that one over. Carrying only changes how the total is written, not its value.
- Counting is slow: if we can count one dot per second, then going from 3-digit to 4-digit numbers gives $10$ times as many dots, and going to 5-digit numbers gives $100$ times as many.
- Digit-by-digit is fast: each extra digit adds only one more column. Going from 3 digits to 4 digits adds $1$ column, and to 5 digits adds $2$ columns.
| Method | Work grows with | 3 digits to 4 digits | 3 digits to 5 digits |
|---|---|---|---|
| Counting dots | The value of the numbers | $10$ times the work | $100$ times the work |
| Column addition | The number of digits | $1$ more column | $2$ more columns |
- Why start here: other methods exist (prime factorisation, for example), but an algorithm built straight from the definition is easy to justify as correct.
- Strategy: splitting a big problem into smaller steps that are already solved is the key habit in designing algorithms.
- Divisors = factors: every divisor of $n$ lies between $1$ and $n$. The simplest method is to check each number from $1$ to $n$ and see whether it divides $n$.
- List: to remember the divisors found so far, we keep them in a sequence called a list, written in square brackets. The empty list is $[\;]$.
- Building the list: start with an empty list. Each time a new divisor is found, add it at the end.
- Executing: at each $j$ either the list grows by one number (if $j$ divides $n$) or it stays unchanged (if it does not).
- Output is in increasing order: $j$ is checked systematically from $1$ upward, so the list comes out sorted. It always starts with $1$ and ends with $n$, because both always divide $n$.
- Basic step assumed: we know how to tell whether a smaller number divides a larger number.
- Amount of work: $n$ checks are needed, so the work grows as the number grows.
- Reusing an algorithm: Steps 1 and 2 use the divisors algorithm as a building block. Larger algorithms are made from smaller ones.
- Why the rightmost element: divisors-of-m is in increasing order, so common-divisors is also in increasing order. Its rightmost element is the largest common divisor, which is the gcd.
- The list is never empty: $1$ divides every number, so $1$ is always a common divisor.
- Why we need an algorithm: for large numbers the lists are very long, and it is no longer possible to find the largest common element by inspection. A systematic procedure is needed.
- Intermediate quantities: while an algorithm runs, it computes values along the way, such as the lists of divisors. We name them (for example divisors-of-m) so that we can refer to them later.
- More than simple numbers: these values are often more complicated than single numbers. Here they are lists, and in fact lists arranged in ascending order.
- Why it matters: a well-chosen data structure makes an algorithm shorter to describe and faster to run. This idea is explored further in higher classes.
Compute both lists together
Instead of two separate scans ($m + n$ checks), scan each $j$ from $1$ to $\max(m, n)$ once. If $j$ divides $m$, add it to the list of $m$; if $j$ divides $n$, add it to the list of $n$. The checks fall from $m + n$ to $\max(m, n)$.
Directly find common divisors
For each $j$ from $1$ to $\max(m, n)$, if $j$ divides both $m$ and $n$, add $j$ to the list of common divisors. No separate lists of divisors are needed.
A smaller range
A common divisor cannot be larger than the smaller number, so it is enough to scan $j$ from $1$ to $\min(m, n)$.
Do away with lists
Each time a larger common divisor is found, the earlier ones are useless. Keep one value, most-recent-common-divisor, starting at $1$. For each $k$ from $2$ to $\min(m, n)$, if $k$ divides both, update it to $k$. At the end it is the gcd.
- Why the last update is the gcd: $k$ increases from $2$ upward, so the last number that divided both is the largest common divisor.
- Scanning backwards: if we scan from $\min(m, n)$ down to $1$, the first $j$ that divides both is already the gcd, so the scan can stop there. If the divisors of a number are listed from $n$ down to $1$, the list comes out in decreasing order, and the gcd becomes the leftmost common divisor instead of the rightmost.
- Divisors occur in pairs: if $j$ divides $n$, then so does $\dfrac{n}{j}$. Checking only up to $\sqrt{n}$ finds every divisor, because each one comes with its partner (a repeated pair is counted once).
- Caution with pairs: a list built in pairs is not in increasing order, so "take the rightmost element" no longer gives the largest. The list must be sorted, or the largest common divisor must be picked out explicitly.
- Correctness is preserved: each refinement changes how the work is organised, not what is computed.
- Correctness: the first algorithm follows directly from the definition of gcd, so it is easy to justify. Every refinement keeps the same result, so all the versions give the correct gcd.
- Efficiency: even the final version examines every number from $1$ to $\min(m, n)$. If the smaller number grows from 3 digits to 4 digits, the scan is $10$ times as long; for 5 digits, $100$ times as long.
- Same problem as counting: the work is proportional to the value of the number, not to the number of digits used to write it.
- The goal: find an algorithm for gcd whose effort is proportional to the number of digits, just as column addition is.
- Reducing a problem to a simpler one: the new pair involves smaller numbers, so the problem becomes easier. The same step is applied again and again.
- Purpose of Step 1: it ensures $m \ge n$, so that $m - n$ is never negative.
- When to stop: the gcd of a number with itself is that number. Reducing $\gcd(m, m)$ gives $\gcd(m, 0)$, so once the second number becomes $0$ the answer is the first number.
- Still slow: when one number is much smaller than the other, the same small number is subtracted many times. For example, $\gcd(2k + 1, 2)$ needs about $k$ reductions before the answer $1$ appears.
- Conclusion: the number of steps is proportional to the value of the numbers, not to their number of digits. The original goal has not yet been reached.
- History: Euclid wrote this method in his book Elements. Other Greek mathematicians probably knew it earlier, but he was the first to put it in writing.
- The idea: repeatedly subtracting $n$ from $m$ until you cannot subtract any more leaves exactly the remainder of $m \div n$. So all those subtractions can be replaced by a single division.
- Why it is still correct: by the same argument as before, a divisor $d$ divides both $m$ and $n$ if and only if it divides both $n$ and $m \bmod n$. The pairs share the same common divisors, so the gcd is unchanged.
- Only one change: in Euclid's algorithm, Step 3 changes from "$\gcd(n, m - n)$" to "$\gcd(n, m \bmod n)$". The stopping condition stays the same.
- Long-division form: divide the larger number by the smaller one. Then divide the previous divisor by the remainder, and keep repeating. The divisor in the division whose remainder is $0$ is the gcd.
- Speed: the number of reductions is now proportional to the number of digits of $m$ and $n$, which meets the goal of the chapter. The proof of this fact is left for later classes.
- Large gap between numbers: a case such as $\gcd(2k + 1, 2)$ now needs only two reductions, however large $k$ is.
- Source: this "long division" method appears in Indian treatises such as Āryabhaṭa's Āryabhaṭīya (499 CE), using Indian place-value numerals.
- Common mix-up: $m \bmod n$ is a remainder, not the difference $m - n$.
- Meaning today: the word first meant an Indian method of arithmetic. It later broadened to mean any well-defined, step-by-step, systematic procedure for solving a class of problems.
- Euclid: first to write down the subtraction algorithm for gcd, in Elements.
- Āryabhaṭa (499 CE): long-division method for gcd in the Āryabhaṭīya.
| Term | Meaning |
|---|---|
| Algorithm | A systematic, step-by-step procedure to solve a problem |
| Executing | Running through the steps of an algorithm one by one |
| Basic step | A step we assume we can perform directly |
| Repetition (loop) | Doing the same step for each value in a sequence, such as each $j$ in $1, 2, \dots, n$ |
| Conditional step | A step done only when a condition is true |
| List | An ordered sequence of values, written in square brackets; the empty list is $[\;]$ |
| Data structure | A way of organising information to help an algorithm work efficiently |
| Correctness | The algorithm really gives the right answer, and this must be justified |
| Efficiency | How the number of steps grows with the size of the input |
| gcd algorithm | Main idea | Work grows with |
|---|---|---|
| First algorithm | List divisors of both numbers, compare lists | About $m + n$ checks |
| Scans combined | One scan from $1$ to $\max(m, n)$ | About $\max(m, n)$ checks |
| Common divisors only | Scan from $1$ to $\min(m, n)$ | About $\min(m, n)$ checks |
| No lists | Keep only most-recent-common-divisor | About $\min(m, n)$ checks |
| Euclid (subtraction) | $\gcd(m, n) = \gcd(n, m - n)$ | The value of the numbers |
| Āryabhaṭa (division) | $\gcd(m, n) = \gcd(n, m \bmod n)$ | The number of digits |
Write precise steps
Use basic steps, names for values, repetition and conditions, so that anyone can follow the steps without guessing.
Prove it is correct
Show why the result is the one required, for example by grouping in place values or by showing the common divisors do not change.
Count the steps
Compare the steps to the size of the input. Steps that follow the number of digits are far better than steps that follow the value.
• Not aligning the digits from the right while adding.
• Leaving out Step 5 (the final carry) in the addition algorithm.
• Forgetting that a column total of exactly $10$ also gives a carry.
• Assuming $1$ is not a common divisor, or forgetting that $1$ and $n$ are always divisors of $n$.
• Starting Euclid's algorithm with $m < n$ without reversing the numbers.
• Reporting $n$ instead of $m$ when $n = 0$; the answer at that point is $m$.
• Confusing $m \bmod n$ (the remainder) with $m - n$.
• Taking the "rightmost element" as the gcd when the list is not in increasing order.
• Thinking a faster-looking refinement changes the answer; it changes only the amount of work.
• Believing Euclid's subtraction algorithm takes steps in proportion to the number of digits; only the division version does.