Math Algorithms: Code Templates in 6 Languages
If you have not read the concept guide , start there for the intuition and the complexity analysis. This page holds the three primitives worth memorizing for interview math. They are the Euclidean GCD, fast modular exponentiation, and the Sieve of Eratosthenes. The first two run in
Main Template: Euclidean GCD
The Euclidean algorithm finds the greatest common divisor by replacing the larger of two numbers with the remainder of dividing it by the smaller one. The loop ends when the remainder is zero, and the last nonzero divisor is the answer.
Use this for Water and Jug Problem .
function gcd(a, b) {
while (b !== 0) {
// The remainder is always smaller than b, so each
// step shrinks the pair toward the case b == 0
[a, b] = [b, a % b];
}
return a;
}Code Breakdown
Key Variables
a,b: the working pair. After each step,aholds the previous divisor andbholds the new remainder.temp: only needed in languages without parallel assignment (Java, C++). It holds one value during the swap.
Visual Mechanism
stateDiagram-v2
[*] --> Loop: a, b
Loop --> Swap: b != 0
Swap --> Loop: replace with (b, a mod b)
Loop --> Done: b == 0
Done --> [*]: return a
Critical Sections
The termination condition is the whole trick. When b reaches zero, a divides both original inputs exactly, so it is the GCD. The loop is fast because a remainder is always smaller than the divisor that produced it, so the pair shrinks on every iteration. That is the difference between this loop and a scan over every possible divisor.
The swap is the only data movement. Parallel assignment in Python, JavaScript, Go, and Ruby makes it a single line. Java and C++ need the temporary variable because the assignment happens one operand at a time.
If you need the least common multiple, derive it from the GCD. LCM(a, b) = a / GCD(a, b) * b. Divide before multiplying so the intermediate value stays small.
Variations
1. Fast Exponentiation (Modular)
Use this when the exponent can be huge, or when results must stay bounded. Squaring the base and halving the exponent cuts the work from N multiplications to about log2(N). Apply the modulus after every multiply so the values stay small in fixed-width languages.
Use this for Pow(x, n) and Super Pow .
Time
function modPow(base, exponent, modulus) {
if (modulus === 1) return 0;
let result = 1;
base = base % modulus;
while (exponent > 0) {
// When the lowest bit of the exponent is set,
// the current power belongs in the result
if (exponent % 2 === 1) {
result = (result * base) % modulus;
}
// Squaring the base handles the next bit of the exponent
base = (base * base) % modulus;
exponent = Math.floor(exponent / 2);
}
return result;
}2. Sieve of Eratosthenes
Use this when you need every prime up to a bound, or when one problem asks many prime checks. The sieve marks each composite once per prime factor instead of checking every candidate against every smaller number.
Use this for Count Primes .
Time
function sieve(limit) {
if (limit < 2) return [];
const isPrime = new Array(limit + 1).fill(true);
isPrime[0] = isPrime[1] = false;
for (let i = 2; i * i <= limit; i++) {
if (isPrime[i]) {
// Start at i*i: smaller multiples were already
// marked by a smaller prime factor
for (let j = i * i; j <= limit; j += i) {
isPrime[j] = false;
}
}
}
const primes = [];
for (let i = 2; i <= limit; i++) {
if (isPrime[i]) primes.push(i);
}
return primes;
}Now head to the practice problems to apply these templates to real interview questions.