ExamplesBy LevelBy TopicLearning Paths
832 Fundamental

Extended Euclidean Algorithm

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Extended Euclidean Algorithm" functional Rust example. Difficulty level: Fundamental. Key concepts covered: Functional Programming. The basic Euclidean algorithm finds gcd(a, b) but not the coefficients. Key difference from OCaml: | Aspect | Rust | OCaml |

Tutorial

The Problem

The basic Euclidean algorithm finds gcd(a, b) but not the coefficients. The extended version also finds Bezout coefficients x, y such that a*x + b*y = gcd(a, b). These coefficients are essential for computing modular inverses (when gcd(a, m) = 1, x is a's inverse mod m), solving linear Diophantine equations ax + by = c, and implementing CRT. Without the extended algorithm, modular inverse requires Fermat's little theorem (only works for prime moduli) or Euler's theorem (requires phi(m), harder to compute). Extended GCD works for any modulus, not just primes.

🎯 Learning Outcomes

  • • Understand the recursive structure: if extended_gcd(b, a%b) = (g, x1, y1), then for the original pair: x = y1, y = x1 - (a/b)*y1
  • • Derive Bezout coefficient update via the recurrence relationship
  • • Apply to modular inverse: mod_inv(a, m) = x mod m where (g, x, _) = extended_gcd(a, m) and g = 1
  • • Solve general linear Diophantine ax + by = c: has solution iff gcd(a,b) divides c
  • • Understand sign handling: Bezout coefficients can be negative
  • Code Example

    #![allow(clippy::all)]
    //! Placeholder

    Key Differences

    AspectRustOCaml
    Negative modulorem_euclid for mathematical mod((x mod m) + m) mod m
    Return typeTuple (i64, i64, i64)Tuple (int * int * int)
    Stack safetyTail-recursive iter preferredTCO makes recursion safe
    Modular inverseReturns Option<i64>Returns int option
    Bezout signsCan be negative (correct)Same
    Integer sizei64 for 64-bit inputsint (63-bit) or Int64

    OCaml Approach

    OCaml's recursive extended GCD returns (int * int * int) exactly as in Rust. The pattern let (g, x1, y1) = extended_gcd b (a mod b) in (g, y1, x1 - (a / b) * y1) is identical in structure. OCaml handles negative remainders from mod differently: (-7) mod 3 = -1 in OCaml (truncating division), requiring explicit adjustment. The ((x mod m) + m) mod m idiom ensures non-negative modular inverse. OCaml's Int.rem has the same truncating behavior.

    Full Source

    #![allow(clippy::all)]
    //! Placeholder

    Deep Comparison

    OCaml vs Rust: Extended Euclidean

    Overview

    See the example.rs and example.ml files for detailed implementations.

    Key Differences

    AspectOCamlRust
    Type systemHindley-MilnerOwnership + traits
    MemoryGCZero-cost abstractions
    MutabilityExplicit refmut keyword
    Error handlingOption/ResultResult<T, E>

    See README.md for detailed comparison.

    Exercises

  • Verify the extended GCD output: for all tested pairs (a, b), check that a*x + b*y == gcd(a,b).
  • Implement iterative extended GCD to avoid stack depth issues for large inputs.
  • Solve the linear Diophantine equation ax + by = c or report no solution, using extended GCD.
  • Use the extended GCD to implement CRT for two congruences without explicitly computing phi.
  • Implement a batch modular inverse computation for a list of values mod p using the recurrence inv[i] = -(p/i) * inv[p%i] mod p.
  • Open Source Repos