Definition
Shared factors
d is common if a % d == 0 and b % d == 0.
Common divisors are positive integers that divide both inputs exactly. This tutorial covers the gcd characterization, a live preview, algorithm steps, worked C examples, edge cases, and complexity.
Shared factors
d is common if a % d == 0 and b % d == 0.
Key theorem
Common divisors of a and b are exactly the divisors of gcd(|a|, |b|).
Up to min
Try every i from 1 to min(|a|, |b|) and keep shared factors.
Euclidean gcd
Compute g, then list divisors of g only.
Try any pair
Enter two integers and list all positive common divisors.
O / sqrt
Naive O(min); gcd + O(sqrt(g)) divisor scan is the interview upgrade.
Common divisors are the positive integers that divide both a and b with remainder 0. Example: divisors of 12 are 1, 2, 3, 4, 6, 12 and of 18 are 1, 2, 3, 6, 9, 18 — shared list is 1, 2, 3, 6.
The elegant framing: if g = gcd(|a|, |b|), then the positive common divisors are exactly the divisors of g. That turns a two-number problem into a one-number divisor listing task.
It connects remainder checks, Euclidean gcd, and divisor enumeration — core number-theory tools for interviews.
Both remainders must be zero.
List divisors of gcd only.
Signs do not change positive divisors.
No finite list of common divisors.
In short: find g = gcd(|a|, |b|), then list every positive divisor of g.
Given two integers, print all positive integers that divide both exactly.
// 24 and 36 → gcd = 12 → divisors 1, 2, 3, 4, 6, 12 | Item | Type | Description |
|---|---|---|
a, b | int | Any integers (use absolute values for positive divisors). |
| Return / print | int buffer + count | Sorted positive common divisors (empty if both are 0). |
function commonDivisorsNaive(a, b):
a = abs(a), b = abs(b)
limit = min(a,b) > 0 ? min(a,b) : max(a,b)
for i from 1 to limit:
if a % i == 0 and b % i == 0:
output i | Method | Idea | Notes |
|---|---|---|
| Naive scan | Check every i up to min(|a|, |b|) | Clearest for beginners |
| GCD + linear divisors | List every divisor of g = gcd | O(g) after Euclidean step |
| GCD + sqrt divisors | Pair factors up to √g | Interview optimization |
| Goal | Pattern |
|---|---|
| Shared factor check | a % i == 0 && b % i == 0 |
| Absolute values | a = abs(a); b = abs(b); |
| Compute gcd | gcd(a, b) |
| Divisors of g | for (i = 1; i <= g; i++) if (g % i == 0) |
| Classic pair | 24, 36 → 1, 2, 3, 4, 6, 12 |
| Both zero | Return empty / report no finite list |
Same common-divisor list — different speed and interview signaling.
scan to minEasy to explain; slow when both numbers are large
divisors of gUses the theorem; loop length is g, not min(a,b)
O(√g)Pair each i with g / i when i divides g
state gcd firstSay the characterization before writing loops
Reach for common-divisor drills when gcd and factor listing matter.
Checks remainder logic and whether you know the gcd theorem.
Gives a concrete reason to compute gcd beyond “largest shared factor.”
Shared factors show up when simplifying ratios and grids.
Often a sub-step inside larger gcd / divisor problems.
This problem is specifically about factors shared by two numbers.
Key benefit: one short problem that teaches gcd theory, remainder loops, and divisor-listing optimizations together.
Enter two integers and list all positive common divisors.
Three complete C programs — naive scan, gcd + linear divisors, and gcd + sqrt factor pairs. Click View Output to reveal sample console results.
Direct scan — the clearest beginner approach.
Take absolute values, then test every candidate up to the smaller magnitude.
#include <stdio.h>
#include <stdlib.h>
int commonDivisorsNaive(int a, int b, int out[], int cap) {
int i;
int count = 0;
int limit;
a = abs(a);
b = abs(b);
if (a == 0 && b == 0) {
return 0;
}
limit = (a < b ? a : b);
if (limit == 0) {
limit = (a > b ? a : b);
}
for (i = 1; i <= limit; i++) {
if (a % i == 0 && b % i == 0) {
if (count < cap) {
out[count++] = i;
}
}
}
return count;
}
int main(void) {
int result[128];
int n = commonDivisorsNaive(24, 36, result, 128);
int i;
printf("Common divisors of 24 and 36 are: [");
for (i = 0; i < n; i++) {
if (i) {
printf(", ");
}
printf("%d", result[i]);
}
printf("]\n");
return 0;
} After handling (0, 0), the loop upper bound is the smaller positive magnitude (or the nonzero value if one input is 0). Each i that divides both is appended.
Use the theorem: common divisors = divisors of gcd.
Cleaner mathematically and often faster when gcd is small.
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b) {
while (b != 0) {
int t = a % b;
a = b;
b = t;
}
return a;
}
int commonDivisorsViaGcd(int a, int b, int out[], int cap) {
int i;
int count = 0;
int g;
a = abs(a);
b = abs(b);
if (a == 0 && b == 0) {
return 0;
}
g = gcd(a, b);
for (i = 1; i <= g; i++) {
if (g % i == 0) {
if (count < cap) {
out[count++] = i;
}
}
}
return count;
}
int main(void) {
int result[128];
int n = commonDivisorsViaGcd(-12, 18, result, 128);
int i;
printf("Common divisors of -12 and 18 are: [");
for (i = 0; i < n; i++) {
if (i) {
printf(", ");
}
printf("%d", result[i]);
}
printf("]\n");
return 0;
} A Euclidean gcd runs in roughly O(log min). Then you only scan 1…g instead of 1…min(a, b). Negatives are normalized with abs first.
Enumerate factors of g in O(√g) time.
For each i ≤ √g that divides g, also collect g / i.
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b) {
while (b != 0) {
int t = a % b;
a = b;
b = t;
}
return a;
}
int commonDivisorsSqrt(int a, int b, int out[], int cap) {
int i;
int g;
int smallCount = 0;
int large[128];
int largeCount = 0;
int count = 0;
a = abs(a);
b = abs(b);
if (a == 0 && b == 0) {
return 0;
}
g = gcd(a, b);
for (i = 1; i * i <= g; i++) {
if (g % i == 0) {
if (smallCount < cap) {
out[smallCount++] = i;
}
{
int other = g / i;
if (other != i && largeCount < 128) {
large[largeCount++] = other;
}
}
}
}
/* append large partners in ascending order */
count = smallCount;
for (i = largeCount - 1; i >= 0; i--) {
if (count < cap) {
out[count++] = large[i];
}
}
return count;
}
void printList(const int v[], int n) {
int i;
printf("[");
for (i = 0; i < n; i++) {
if (i) {
printf(", ");
}
printf("%d", v[i]);
}
printf("]\n");
}
int main(void) {
int buf[256];
int n;
n = commonDivisorsSqrt(24, 36, buf, 256);
printList(buf, n);
n = commonDivisorsSqrt(7, 11, buf, 256);
printList(buf, n);
return 0;
} Small factors go into small; matching large partners into large. appending large in reverse at the end yields ascending order without a full sort.
Take absolute values; reject or special-case (0, 0).
Compute g = gcd(a, b) with the Euclidean algorithm.
Linear scan 1…g, or collect factor pairs up to √g.
Return the sorted positive divisors of g — that is the full common list.
Trace the gcd route. Euclidean steps, then divisors of g = 12.
| Step | Action | Result |
|---|---|---|
| 1 | gcd(36, 24) | 36 % 24 = 12 |
| 2 | gcd(24, 12) | 24 % 12 = 0 → g = 12 |
| 3 | Divisors of 12 | 1, 2, 3, 4, 6, 12 |
Final common divisors: 1, 2, 3, 4, 6, 12.
Where common-divisor listing shows up beyond the interview prompt.
Tests remainder checks and gcd awareness.
Example: list common divisors of 24 and 36.
Makes the “divisors of gcd” theorem concrete.
Example: chalkboard 12 and 18.
Shared factors are what cancel in a / b.
Example: reduce 24/36 by dividing by 12.
Common tile sizes that fit two dimensions exactly.
Example: tile a 24×36 board.
Often a helper inside larger divisor / gcd problems.
Example: enumerate candidates dividing both n and m.
Compare O(min) vs O(log + √g) convincingly.
Example: “why gcd first?”
Pro Tip: say the gcd characterization out loud before coding — interviewers often score that explanation as highly as the loop.
Why the gcd framing works so well.
Common divisors = divisors of gcd — one sentence that drives the code.
A short while (b != 0) loop keeps the gcd step clear and correct.
Sqrt divisor listing is a natural upgrade from the linear scan.
Signs, zeros, and coprime pairs give structured follow-ups.
Pro Tip: if asked for only the count of common divisors, still compute gcd first — then count divisors of g.
Small habits that keep common-divisor solutions interview-ready.
Explain before coding — it shows number-theory fluency.
Positive divisors depend on magnitude, not sign.
Return an empty list or throw — document the choice.
Expect 1, 2, 3, 4, 6, 12 as a golden test.
Mention O(√g) when gcd can be huge.
Pro Tip: for one input 0, common divisors are just the divisors of the nonzero number — gcd already encodes that.
Mistakes that commonly break common-divisor solutions.
Negative inputs can confuse homemade loops.
→ Normalize with abs before scanning.
There is no finite complete list of common divisors.
→ Return an empty list or throw with a clear message.
A common divisor cannot exceed the smaller positive magnitude.
→ Cap naive loops at min, or better — use gcd.
When i * i == g, appending both sides twice is wrong.
→ Only add the pair partner when other != i.
gcd is the largest common divisor, not the only one.
→ Still enumerate all divisors of g when asked for common divisors.
Check these inputs before calling the solution done.
No finite list to display.
Use absolute values before gcd/divisor checks.
Common divisors are the divisors of |n|.
Only common divisor is 1 (e.g. 7 and 11).
Listing all divisors can be large output — prefer O(√g).
Common divisors are simply all positive divisors of |a|.
Handy follow-ups interviewers sometimes ask.
lcm(a, b) = a / gcd(a, b) * b.Try these variations to lock in the pattern.
Quick Takeaway: compute g = gcd(|a|, |b|), then list every positive divisor of g.
| Program | Time | Extra space |
|---|---|---|
| Naive scan | O(min(|a|, |b|)) | O(1) (+ output) |
| GCD + linear divisor scan | O(log min + g) | O(1) (+ output) |
| GCD + sqrt divisor pairs | O(log min + √g) | O(1) (+ output) |
Common divisors are shared exact factors — and equivalently, the positive divisors of gcd(|a|, |b|). Start with a naive scan if needed, then upgrade to gcd + divisor listing (linear or sqrt).
Practice the three examples above, then continue to prime numbers for another classic number-theory warm-up.
Always use abs, handle (0, 0), state the gcd theorem, and prefer O(√g) divisor listing when g can be large.
List shared factors the interview-friendly way.
d divides both
DefinitionDivisors of gcd
MathUse abs first
GuardO(√g) listing
Code(0,0) special
AnalysisEvery common divisor of a and b divides gcd(a, b), and every divisor of gcd(a, b) is a common divisor.
Learn how to check whether a number is prime with trial division and sqrt optimizations.
9 people found this page helpful