84. Fraction to Recurring Decimal
mediumAsked at VercelConvert a fraction to a string, marking any recurring decimal with parentheses. Vercel asks this to see whether you can handle multiple edge cases (sign, overflow, recurrence detection) with a hash-map cycle detector.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Vercel loops.
- Glassdoor (2025-Q4)— Vercel platform onsite; cycle detection on remainder expected.
- Blind (2026-Q1)— Listed in Vercel screen pool.
Problem
Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. If the fractional part is repeating, enclose the repeating part in parentheses. If multiple answers are possible, return any of them. It is guaranteed that the length of the answer string is less than 10^4 for all the given inputs.
Constraints
-2^31 <= numerator, denominator <= 2^31 - 1denominator != 0
Examples
Example 1
numerator = 1, denominator = 2"0.5"Example 2
numerator = 2, denominator = 1"2"Example 3
numerator = 4, denominator = 333"0.(012)"Approaches
1. Naive long division without cycle detection
Long-divide and emit digits.
- Time
- infinite for recurring
- Space
- infinite
// Never terminates for 1/3. Must detect cycles.Tradeoff: Broken.
2. Long division with remainder->index map (optimal)
Convert to absolute BigInt; integer part is num / den. For fraction, track remainders in a map of remainder -> position in output. When remainder repeats, wrap the recurring part in parens.
- Time
- O(d) where d = decimal expansion length
- Space
- O(d)
function fractionToDecimal(num, den) {
if (num === 0) return '0';
let s = '';
if ((num < 0) !== (den < 0)) s += '-';
num = Math.abs(num); den = Math.abs(den);
s += Math.floor(num / den);
let rem = num % den;
if (rem === 0) return s;
s += '.';
const map = new Map();
while (rem !== 0) {
if (map.has(rem)) {
const idx = map.get(rem);
return s.substring(0, idx) + '(' + s.substring(idx) + ')';
}
map.set(rem, s.length);
rem *= 10;
s += Math.floor(rem / den);
rem %= den;
}
return s;
}Tradeoff: The map tracks remainders we've seen and where in the output they landed. When the same remainder repeats, we know the digits between will repeat forever — wrap with parens.
Vercel-specific tips
Vercel grades the cycle detection. Bonus signal: handling sign carefully (XOR of sign bits) and overflow (32-bit MIN_VALUE's absolute value overflows; cast to BigInt or to a wider type). Articulate the edge cases out loud before coding.
Common mistakes
- Forgetting the integer-only case (rem === 0 after division) — adds spurious '.'.
- Sign handling — XOR-the-signs, then make both absolute.
- Overflow on Math.abs(-2^31) — in JS it's fine, but flag the issue for typed languages.
Follow-up questions
An interviewer at Vercel may pivot to one of these next:
- Add two fractions and return the result as a recurring decimal.
- Parse a recurring decimal back to a fraction.
- Detect the start of the recurring part more efficiently.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why does remainder-cycle detect decimal recurrence?
In long division, each digit depends only on the current remainder. If a remainder repeats, all future digits will also repeat — that's the definition of a repeating decimal.
Why store the output position?
We need to know where to INSERT the open paren. The map remembers 'remainder X produced the digit at output position Y' — when X reappears, we wrap from Y.
Practice these live with InterviewChamp.AI
Drill Fraction to Recurring Decimal and other Vercel interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →