Number Theory
Euclidean Algorithm

Greatest Common Divisor

Greatest Common Divisor or commonly known as gcd of two integers is greatest common integer that completely divides both of them.

gcd(a,b)=maxdZ+:da and db\gcd(a,\,b) = \max{d \in \mathbb{Z}^+ : d\,|\,a \text{ and } d\,|\,b}

dad\,|\,a means d divides a

gcd(0,a)=agcd(0,\, a) = a
gcd(0,0)=undefinedgcd(0,\, 0) = undefined

Euclidean Algorithm

  • Problem :- Find gcd(a,b)gcd(a,\, b)
    Naive way of doing this would be to just iterate over all integers in reverse order until you find an integer that divides both aa and bb.
    Time complexity - O(min(a,b))O(min(a,\, b))

  • Intuition behind Euclidean Algorithm to solve this problem efficiently

    Let's say dd is some integer that divides both aa and bb. Then we can prove dd also divides aba - b.
    Proof -
    (ab)%d=((a%d)(b%d)+d)%d(a - b) \,\% \,d = ((a \,\%\, d) - (b \,\%\, d) + d) \,\%\,d
    (ab)%d=(00+d)%da%d=0b%d=0(a - b) \,\% \,d = (0 - 0 + d) \,\%\,d \,\,\,\,\,\,\,\,\,\because a \,\%\, d = 0\, \, \,b \, \%\, d = 0
    (ab)%d=d%d=0\therefore (a - b) \,\% \,d = d\,\%\,d = 0 \,\blacksquare

    Let's build further intuition on this proof. Let aa be represented as (bq)+r(b * q) + r \, \mid qq is quotientquotient and rr is remainderremainder.
    Now we can prove that dd also divides rr. Here is the proof

    • a=(bq)+ra = (b * q) + r

    • a%d=((bq)+r)%da\,\%\,d = ((b * q) + r)\,\%\,d

    • 0=((bq)+r)%da%d=00 = ((b * q) + r)\,\%\,d \,\,\,\,\,\,\,\because a\,\%\,d = 0

    • ((bq)+r)%d=((bq)%d)+(r%d)=0((b * q) + r)\,\%\,d = ((b * q)\%\,d) + (r\,\%\,d) = 0

    • ((bq)%d)+(r%d)=(((b%d)(q%d))+(r%d)=0((b * q)\%\,d) + (r\,\%\,d) = (((b\,\%\,d) * (q\,\%\,d)) + (r\,\%\,d) = 0

    • ((bq)%d)+(r%d)=((0(q%d))+(r%d))=0(b%d=0)((b * q)\%\,d) + (r\,\%\,d) = ((0 * (q\,\%\,d)) + (r\,\%\,d)) = 0 \because (b\,\%\,d = 0)

    • (0+(r%d))=(r%d)=0(0 + (r\,\%\,d)) = (r\,\%\,d) = 0 \,\blacksquare

      Let's see why this helps :
      If a number divides both aa and bb then it must also divide rr because (r=a(bq))(r = a - (b * q))
      So gcd(a,b)=gcd(b,r)gcd(a, \,b) = gcd(b,\,r)

    • Example

      • Let's see a concrete example with 4848 and 1818:

      • 48=182+1248 = 18 * 2 + 12 (First divide 4848 by 1818)

      • 18=121+618 = 12 * 1 + 6 (Then divide 1818 by 1212)

      • 12=6×2+012 = 6 × 2 + 0 (Finally divide 1212 by 66)

      • At each step, we're reducing the problem to finding gcd of smaller numbers
        GCD(48,18)=GCD(18,12)=GCD(12,6)=6GCD(48,18) = GCD(18,12) = GCD(12,6) = 6

        Why this algorithm works ?

      • Each remainder is strictly smaller than the previous divisor

      • The remainders keep getting smaller

      • They can't go below zero

      • So the process must eventually terminate when we get remainder 00

      • The last non-zero remainder is our gcd

Recursive Definition (Euclidean Algorithm)

  • gcd(a,b)={awhen b=0;gcd(b,amodb)when b0\gcd(a,b) = \begin{cases} |a| & \text{when } b = 0 \,;\, \gcd(b, a \bmod b) & \text{when } b \neq 0 \end{cases}
static int gcd(int a, int b) {
    return b == 0 ? a : gcd(b , a % b);
}
  • Time Complexity O(log2(max(a,b)))O(log_2(max(a,\, b)))