From 43e7db4e888348ed875ef8f07e7da588ff124a78 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Tue, 9 Dec 2025 10:48:38 -0600 Subject: [PATCH] fix(practice): check all later prefix sums for ambiguity, not just final answer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, typing "3" for problem [2, 1, 30, 10, 1] with prefix sums [2, 3, 33, 43, 44] would immediately show help for prefix sum 3 because the code only checked if "3" was a digit-prefix of the final answer (44). Now it correctly checks if "3" could be a digit-prefix of ANY later prefix sum (33 in this case), making it ambiguous and allowing the user to continue typing "33" to get help for that prefix instead. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../hooks/__tests__/useInteractionPhase.test.ts | 12 ++++++++++++ .../practice/hooks/useInteractionPhase.ts | 15 ++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/apps/web/src/components/practice/hooks/__tests__/useInteractionPhase.test.ts b/apps/web/src/components/practice/hooks/__tests__/useInteractionPhase.test.ts index 0b7a13f9..c940ae48 100644 --- a/apps/web/src/components/practice/hooks/__tests__/useInteractionPhase.test.ts +++ b/apps/web/src/components/practice/hooks/__tests__/useInteractionPhase.test.ts @@ -129,6 +129,18 @@ describe('findMatchedPrefixIndex', () => { expect(result.helpTermIndex).toBe(2) // help with term at index 2 }) + it('detects ambiguous match when prefix sum is digit-prefix of intermediate prefix sum', () => { + // Problem: [2, 1, 30, 10, 1] -> prefix sums [2, 3, 33, 43, 44] + // Typing "3" matches prefix sum 3 at index 1 + // But "3" is also the first digit of "33" at index 2 + // Note: "3" is NOT a prefix of "43" or "44" (those start with "4") + const multiSums = [2, 3, 33, 43, 44] + const result = findMatchedPrefixIndex('3', multiSums) + expect(result.matchedIndex).toBe(1) // matches prefix sum 3 at index 1 + expect(result.isAmbiguous).toBe(true) // "3" is also digit-prefix of "33" + expect(result.helpTermIndex).toBe(2) // help with term at index 2 + }) + it('returns no match for input that does not match any prefix sum', () => { const result = findMatchedPrefixIndex('5', sums) expect(result.matchedIndex).toBe(-1) diff --git a/apps/web/src/components/practice/hooks/useInteractionPhase.ts b/apps/web/src/components/practice/hooks/useInteractionPhase.ts index a0ef4da4..9d85d376 100644 --- a/apps/web/src/components/practice/hooks/useInteractionPhase.ts +++ b/apps/web/src/components/practice/hooks/useInteractionPhase.ts @@ -219,7 +219,7 @@ export interface PrefixMatchResult { * Finds which prefix sum the user's answer matches, if any. * Also detects ambiguous cases where the input could be either: * 1. An intermediate prefix sum (user is stuck) - * 2. The first digit(s) of the final answer (user is still typing) + * 2. The first digit(s) of a later prefix sum (user is still typing) * * Leading zeros disambiguate and REQUEST help: * - "3" alone is ambiguous (could be prefix sum 3 OR first digit of 33) @@ -241,7 +241,6 @@ export function findMatchedPrefixIndex( if (Number.isNaN(answerNum)) return noMatch const finalAnswer = prefixSums[prefixSums.length - 1] - const finalAnswerStr = finalAnswer.toString() // Check if this is the final answer if (answerNum === finalAnswer) { @@ -265,12 +264,18 @@ export function findMatchedPrefixIndex( } } - // Check if user's input could be a digit-prefix of the final answer - const couldBeFinalAnswerPrefix = finalAnswerStr.startsWith(userAnswer) + // Check if user's input could be a digit-prefix of ANY later prefix sum + // For example, with prefix sums [2, 3, 33, 43, 44]: + // - "3" matches prefix sum at index 1, but could also be first digit of 33 or 43 + // - So "3" is ambiguous + const couldBeLaterPrefixPrefix = prefixSums.slice(matchedIndex + 1).some((laterSum) => { + const laterSumStr = laterSum.toString() + return laterSumStr.startsWith(userAnswer) + }) return { matchedIndex, - isAmbiguous: couldBeFinalAnswerPrefix, + isAmbiguous: couldBeLaterPrefixPrefix, helpTermIndex: matchedIndex + 1, // Help with the NEXT term after the matched sum } }