DSA foundations · Number theory
Number tricks that turn n steps into √n
Digits, divisors, GCD and primes all look like they need a loop up to n. Each one has a shortcut you can derive rather than memorise — and the sieve finds every prime below 30 in 24 pencil strokes.
Strike out the composites up to 30, one prime at a time →01 The idea
Stop looping to n
A number problem hands you one integer and asks something about it. How many digits does it have. What are its divisors. Is it prime. What does it share with a second number. The first loop that comes to mind runs from 1 to n and checks every value on the way. For n = 30 that costs nothing. For n = 10⁹ it is a program that never finishes.
Every technique in this module is the same correction applied four different ways. Digits fall off ten at a time, so a 9-digit number takes 9 turns and not a billion. Divisors come in pairs that meet at √n, so you only ever search one half of each pair. A remainder is always smaller than the number you divided by, so Euclid's GCD collapses in a handful of steps. And when you want every prime below N, you stop asking each number a question and start striking out multiples instead.
02 Worked example
The Sieve of Eratosthenes up to 30
Write the numbers 2 to 30 on paper. Circle the smallest one you have not touched — that is 2, and it must be prime, because nothing smaller crossed it out. Now cross out every multiple of 2 above it. Move to the next uncrossed number and repeat. Each row below is one prime's turn, showing only the numbers it strikes for the first time.
Count what the sieve actually did. It wrote 24 crosses in total — 14 for 2, 8 for 3, 2 for 5 — and 19 of them landed on a number for the first time, which is exactly the number of composites between 2 and 30. It never once asked "is 17 prime?". It found out because nobody crossed 17 out. That is the whole trade: you give up asking about one number and you get every answer in the range at once.
03 Mechanics
Why √n is enough
Before the sieve comes the single-number question: is 29 prime? The obvious loop divides 29 by every number below it. The fix is one line of the loop condition, and it is worth deriving once instead of memorising. Suppose n = a × b and both a and b were greater than √n. Then their product would be greater than n, which contradicts the assumption. So every composite has a divisor at or below √n. Search there, find nothing, and there is nothing to find anywhere.
Naive — divide by everything
isPrime(n): if n < 2: return false for d = 2 to n - 1: if n % d == 0: return false return true
Bounded — stop at the square root
isPrime(n): if n < 2: return false d = 2 while d * d <= n: if n % d == 0: return false d = d + 1 return true
For n = 29 that is 4 divisions instead of 27. The naive loop tries every d from 2 to 28. The bounded loop stops after d = 5, because 6 × 6 = 36 is already past 29. The gap widens with n: at n = 10⁹ it is 31,623 divisions against a billion.
The test is d * d <= n, not d <= sqrt(n). Integer multiplication is exact. sqrt returns a floating-point value, and for large n the rounding can land one below the true root, skip the last divisor and report a composite as prime. Same loop, no floating point, no edge case.
Looping to n/2 is not the same fix. It skips the top half and still costs 13 divisions for 29 instead of 27 — half the work, same growth rate. √n is a different curve, not a smaller constant, and that is the distinction an interviewer is listening for.
The same bound lists every divisor. Walk d from 1 while d * d <= n; each hit hands you two divisors, d and n / d. For 30 the five tests d = 1, 2, 3, 4, 5 produce the pairs (1, 30), (2, 15), (3, 10) and (5, 6) — all 8 divisors from 5 divisions. Add d only once when d * d == n, or a perfect square counts its middle divisor twice.
05 Cheat sheet
Eight routines and what they cost
| Task | Method | Cost |
|---|---|---|
| Count or reverse the digits of n | peel with n % 10, drop with n / 10 | O(log n) |
| Is n prime? | trial-divide d while d*d <= n | O(√n) |
| List every divisor of n | for each d ≤ √n that divides n, take d and n/d | O(√n) |
| Prime factorise n | divide out each d from 2 while d*d <= n, keep the leftover | O(√n) |
| Every prime up to N | Sieve of Eratosthenes | O(N log log N) |
| Test each of 2..N on its own | the √n check, N times | O(N√N) |
| gcd(a, b) | while b: a, b = b, a mod b | O(log min(a,b)) |
| lcm(a, b) and ab mod m | a / g * b; square the base and halve b | O(log n) |
06 Where & why
The sieve is not a primality test
The sieve answers "which numbers in this whole range are prime" in one pass, and it pays for that by needing the entire range in memory before you ask a single question. If you only ever ask about one number, it is the wrong tool and the √n check is the right one.
Reach for the sieve when…
Use something else when…
| Situation | Better choice | Why |
|---|---|---|
| One number with 18 digits | Miller–Rabin | An array of 10¹⁸ flags does not exist. Miller–Rabin answers in a few dozen modular exponentiations, and with a fixed set of bases it is deterministic for every 64-bit input. |
| Primes inside [10⁹, 10⁹ + 10⁶] | Segmented sieve | Sieve only to √(10⁹) ≈ 31,623 for the base primes, then strike their multiples inside the window. Memory tracks the window size, not the endpoint. |
| Factorising one large semiprime | Pollard's rho | Trial division to √n is 10⁹ steps at n = 10¹⁸. Pollard's rho runs in roughly O(n1/4) and is what real factorisation code starts with. |
| You only need gcd or lcm | Euclid | No primes are involved at all. Factorising both numbers to find common factors is far slower and can overflow; the remainder loop finishes in a handful of divisions. |
07 Interview questions
What they actually ask
Number-theory questions turn up in screening rounds because they are short to state and easy to mark. What is being tested is whether you can justify the bound, not whether you remember the loop.
Walk me through the Sieve of Eratosthenes.
Why does the outer loop stop at √N?
Why does the inner loop start at p² and not at 2p?
What is the time and space complexity of the sieve?
Why is it enough to trial-divide a single number up to √n?
Is 1 prime? What about 2, 0 and negative numbers?
Explain Euclid’s algorithm and prove that it terminates.
How many steps does Euclid take?
How do you get the LCM, and what goes wrong?
Sieve or per-number test — how do you choose?
How would you compute a to the power b, mod m, without looping b times?
Where does any of this show up in real code?
08 Practice problems
Six to work through
For each one, state the bound of your loop and why it is enough before you write anything. Every problem here is solvable with the four moves in this lesson and nothing else.