Debugging challengeAdvanced
Rolling hash and bitmask that silently corrupt
Scenario
A Rabin–Karp matcher and a bitmask DP both work in C++ and were ported line by line to JavaScript. The JS version reports false matches on long strings, the DP "visits" states it never set, and a factorial helper returns the wrong value for n = 21. Find the three numeric bugs.
1const MOD = 1e18 + 9;2const BASE = 131;3 4// polynomial rolling hash of s5function hash(s) {6 let h = 0;7 for (const ch of s) h = (h * BASE + ch.charCodeAt(0)) % MOD;8 return h;9}10 11// mark subset of 40 items as visited12function markVisited(visited, mask, item) {13 visited.add(mask | (1 << item));14}15 16function factorial(n) {17 let f = 1;18 for (let i = 2; i <= n; i++) f *= i;19 return f;20}21 22console.log(hash('a'.repeat(30)) === hash('a'.repeat(29) + 'b')); // sometimes true23const visited = new Set();24markVisited(visited, 0, 31);25markVisited(visited, 0, 32);26console.log(visited); // Set { -2147483648, 1 } — item 32 == item 027console.log(factorial(21)); // 51090942171709440000, expected 51090942171709440000? no: 51090942171709440000 is wrongYour task
- What is the largest integer JavaScript can represent exactly? What happens to
h * BASEwhenhis close toMOD? - How many bits do JavaScript bitwise operators use? What is
1 << 32? - At which
ndoesfactorial(n)first lose precision, and why does it not throw? - Fix all three: choose a safe modulus, a safe way to build a 40-bit mask, and exact factorials.
- State the complexity of the fixes and any runtime cost of
BigInt.
DebuggingEdge CasesSystematic Reasoning
Work it out
Write your analysis before revealing anything. The self-check below compares it against what a strong answer contains.
Reveal
Progressive — each section builds on the previous one.
The bug
Why it happens
The fix
Edge cases
Complexity
Self-check
Tick what your analysis covered. Be honest — this feeds your readiness profile.