ExamplesBy LevelBy TopicLearning Paths
827 Intermediate

Modular Arithmetic

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Modular Arithmetic" functional Rust example. Difficulty level: Intermediate. Key concepts covered: Functional Programming. When computing large combinatorial values (n! Key difference from OCaml: | Aspect | Rust | OCaml |

Tutorial

The Problem

When computing large combinatorial values (n! mod p, binomial coefficients, number of paths), intermediate results overflow 64-bit integers long before the final answer. Modular arithmetic performs all operations in a finite field Z/pZ, keeping values bounded. Computing (a + b) % m, (a * b) % m, pow(a, b, m), and inv(a, m) are the building blocks of competitive programming, cryptography, and number theory. The key insight: (a * b) % m = ((a % m) * (b % m)) % m. Modular exponentiation (fast power) runs in O(log b) and is essential for RSA, Diffie-Hellman, and primality testing.

🎯 Learning Outcomes

  • • Implement modular addition, subtraction, and multiplication with proper overflow prevention
  • • Implement fast modular exponentiation via repeated squaring in O(log exp) time
  • • Understand modular inverse and when it exists (only when gcd(a, m) = 1)
  • • Compute factorial and binomial coefficients modulo a prime efficiently
  • • Recognize when to use Fermat's little theorem vs. extended Euclidean for modular inverse
  • Code Example

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

    Key Differences

    AspectRustOCaml
    Overflow risku64 * u64 overflows above 2^32 modint * int overflows above 2^30 mod
    Large modulusUse u128 intermediateUse Int64 or Zarith
    Mod exponentiationIterative with bit manipulationRecursive or iterative
    Modular inversemod_pow(a, m-2, m) for prime mSame via Fermat
    Binomial coefficientsPrecompute factorial array mod pSame approach
    Newtype safetystruct Mod<const M: u64>(u64)type modint = int (no enforcement)

    OCaml Approach

    OCaml's int is 63-bit on 64-bit systems, allowing products up to about 4.6 * 10^18. For moduli up to 2^30, a * b mod m stays in bounds. For larger moduli, OCaml uses Int64 or Zarith. Modular exponentiation is a clean tail-recursive function: let rec pow_mod base exp m = if exp = 0 then 1 else let half = pow_mod (base * base mod m) (exp / 2) m in if exp mod 2 = 0 then half else half * base mod m. OCaml's Fun.protect ensures cleanup in modular operations with side effects.

    Full Source

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

    Deep Comparison

    OCaml vs Rust: Modular Arithmetic

    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

  • Implement a ModInt<const M: u64> newtype that overloads arithmetic operators to auto-apply modular reduction.
  • Precompute factorial and inverse factorial tables mod p to answer n-choose-k queries in O(1).
  • Implement Lucas' theorem for computing binomial coefficients mod a prime p for very large n, k.
  • Use modular arithmetic to verify matrix multiplication: (A * B) % m = ((A % m) * (B % m)) % m.
  • Benchmark u64 vs. u128 intermediate for modular multiplication and measure the throughput difference.
  • Open Source Repos