import type { AlgorithmDefinition } from '@/lib/visualizations/types'; export const prefixSumAlgorithm: AlgorithmDefinition = { id: 'prefix-sum', title: 'Prefix Sum - Range Query', slug: 'prefix-sum', pattern: { name: 'Prefix Sum', description: 'Precompute cumulative sums to answer range sum queries in O(1) time.', }, problemStatement: 'Given an array, answer multiple range sum queries efficiently. Each query asks for the sum of elements from index i to j.', intuition: 'Build a prefix sum array where prefix[k] = sum of all elements from 0 to k-1. Then any range sum from i to j is simply prefix[j+1] - prefix[i].', code: { language: 'python', code: `def build_prefix(nums: list[int]) -> list[int]: prefix = [0] for num in nums: prefix.append(prefix[-1] + num) return prefix def range_sum(prefix: list[int], i: int, j: int) -> int: return prefix[j + 1] - prefix[i]`, }, initialExample: { input: { nums: [3, 1, 4, 1, 5, 9], query: { i: 1, j: 4 } }, expected: 11, }, steps: [ // Phase 1: Problem (2 steps) { id: 'problem-1', phase: 'problem', explanation: 'We have an array [3, 1, 4, 1, 5, 9] and need to efficiently answer range sum queries like "sum from index 1 to 4".', dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, ], pointers: [], variables: [], calculations: [], }, }, { id: 'problem-2', phase: 'problem', explanation: 'Naively summing each range takes O(n) per query. With many queries, this becomes expensive. Can we precompute something?', dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'highlighted' }, { value: 4, index: 2, state: 'highlighted' }, { value: 1, index: 3, state: 'highlighted' }, { value: 5, index: 4, state: 'highlighted' }, { value: 9, index: 5, state: 'normal' }, ], }, ], pointers: [ { id: 'i', name: 'i', index: 1, color: 'left' }, { id: 'j', name: 'j', index: 4, color: 'right' }, ], variables: [ { id: 'i', name: 'i', value: 1 }, { id: 'j', name: 'j', value: 4 }, ], calculations: [], }, }, // Phase 2: Intuition (3 steps) { id: 'intuition-1', phase: 'intuition', explanation: 'Key insight: Build a prefix sum array where each element is the cumulative sum of all elements up to that point.', dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'normal' }, { value: 9, index: 4, state: 'normal' }, { value: 14, index: 5, state: 'normal' }, { value: 23, index: 6, state: 'normal' }, ], }, ], pointers: [], variables: [], calculations: [], }, }, { id: 'intuition-2', phase: 'intuition', explanation: 'prefix[k] represents the sum of elements from index 0 to k-1. The extra 0 at the start simplifies our formula.', dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'highlighted' }, { value: 1, index: 1, state: 'highlighted' }, { value: 4, index: 2, state: 'highlighted' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'highlighted' }, { value: 9, index: 4, state: 'normal' }, { value: 14, index: 5, state: 'normal' }, { value: 23, index: 6, state: 'normal' }, ], }, ], pointers: [], variables: [], calculations: [ { id: 'calc-1', expression: '3 + 1 + 4', result: '8', position: 'above' }, ], }, }, { id: 'intuition-3', phase: 'intuition', explanation: 'Range sum from i to j = prefix[j+1] - prefix[i]. This is O(1) per query after O(n) preprocessing!', dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'highlighted' }, { value: 4, index: 2, state: 'highlighted' }, { value: 1, index: 3, state: 'highlighted' }, { value: 5, index: 4, state: 'highlighted' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'comparing' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'normal' }, { value: 9, index: 4, state: 'normal' }, { value: 14, index: 5, state: 'comparing' }, { value: 23, index: 6, state: 'normal' }, ], }, ], pointers: [ { id: 'i', name: 'i', index: 1, color: 'left' }, { id: 'j+1', name: 'j+1', index: 5, color: 'right' }, ], variables: [ { id: 'i', name: 'i', value: 1 }, { id: 'j', name: 'j', value: 4 }, ], calculations: [ { id: 'calc-1', expression: '14 - 3', result: '11', position: 'above' }, ], }, }, // Phase 3: Code walkthrough (4 steps) { id: 'code-1', phase: 'code', explanation: 'Start with prefix = [0]. This handles the edge case of summing from index 0.', codeLine: 2, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, ], pointers: [], variables: [], calculations: [], }, }, { id: 'code-2', phase: 'code', explanation: 'For each element, append prefix[-1] + num. This builds the cumulative sum.', codeLine: 3, codeHighlightLines: [3, 4], dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, ], pointers: [], variables: [], calculations: [], }, }, { id: 'code-3', phase: 'code', explanation: 'The range_sum function computes prefix[j+1] - prefix[i] in O(1).', codeLine: 8, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, ], pointers: [], variables: [], calculations: [], }, }, { id: 'code-4', phase: 'code', explanation: 'Why j+1? Because prefix[k] is the sum of elements 0 through k-1. So prefix[j+1] includes element j.', codeLine: 8, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, ], pointers: [], variables: [], calculations: [], }, }, // Phase 4: Execution - Building prefix array (10 steps) { id: 'exec-1', phase: 'execution', explanation: 'Initialize prefix = [0].', codeLine: 2, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'highlighted' }, ], }, ], pointers: [], variables: [], calculations: [], }, }, { id: 'exec-2', phase: 'execution', explanation: 'Process nums[0] = 3. Append prefix[-1] + 3 = 0 + 3 = 3.', codeLine: 4, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'comparing' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'highlighted' }, ], }, ], pointers: [ { id: 'curr', name: 'num', index: 0, color: 'mid' }, ], variables: [], calculations: [ { id: 'calc-1', expression: '0 + 3', result: '3', position: 'above' }, ], }, }, { id: 'exec-3', phase: 'execution', explanation: 'Process nums[1] = 1. Append prefix[-1] + 1 = 3 + 1 = 4.', codeLine: 4, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'dimmed' }, { value: 1, index: 1, state: 'comparing' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'highlighted' }, ], }, ], pointers: [ { id: 'curr', name: 'num', index: 1, color: 'mid' }, ], variables: [], calculations: [ { id: 'calc-2', expression: '3 + 1', result: '4', position: 'above' }, ], }, }, { id: 'exec-4', phase: 'execution', explanation: 'Process nums[2] = 4. Append prefix[-1] + 4 = 4 + 4 = 8.', codeLine: 4, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'dimmed' }, { value: 1, index: 1, state: 'dimmed' }, { value: 4, index: 2, state: 'comparing' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'highlighted' }, ], }, ], pointers: [ { id: 'curr', name: 'num', index: 2, color: 'mid' }, ], variables: [], calculations: [ { id: 'calc-3', expression: '4 + 4', result: '8', position: 'above' }, ], }, }, { id: 'exec-5', phase: 'execution', explanation: 'Process nums[3] = 1. Append prefix[-1] + 1 = 8 + 1 = 9.', codeLine: 4, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'dimmed' }, { value: 1, index: 1, state: 'dimmed' }, { value: 4, index: 2, state: 'dimmed' }, { value: 1, index: 3, state: 'comparing' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'normal' }, { value: 9, index: 4, state: 'highlighted' }, ], }, ], pointers: [ { id: 'curr', name: 'num', index: 3, color: 'mid' }, ], variables: [], calculations: [ { id: 'calc-4', expression: '8 + 1', result: '9', position: 'above' }, ], }, }, { id: 'exec-6', phase: 'execution', explanation: 'Process nums[4] = 5. Append prefix[-1] + 5 = 9 + 5 = 14.', codeLine: 4, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'dimmed' }, { value: 1, index: 1, state: 'dimmed' }, { value: 4, index: 2, state: 'dimmed' }, { value: 1, index: 3, state: 'dimmed' }, { value: 5, index: 4, state: 'comparing' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'normal' }, { value: 9, index: 4, state: 'normal' }, { value: 14, index: 5, state: 'highlighted' }, ], }, ], pointers: [ { id: 'curr', name: 'num', index: 4, color: 'mid' }, ], variables: [], calculations: [ { id: 'calc-5', expression: '9 + 5', result: '14', position: 'above' }, ], }, }, { id: 'exec-7', phase: 'execution', explanation: 'Process nums[5] = 9. Append prefix[-1] + 9 = 14 + 9 = 23.', codeLine: 4, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'dimmed' }, { value: 1, index: 1, state: 'dimmed' }, { value: 4, index: 2, state: 'dimmed' }, { value: 1, index: 3, state: 'dimmed' }, { value: 5, index: 4, state: 'dimmed' }, { value: 9, index: 5, state: 'comparing' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'normal' }, { value: 9, index: 4, state: 'normal' }, { value: 14, index: 5, state: 'normal' }, { value: 23, index: 6, state: 'highlighted' }, ], }, ], pointers: [ { id: 'curr', name: 'num', index: 5, color: 'mid' }, ], variables: [], calculations: [ { id: 'calc-6', expression: '14 + 9', result: '23', position: 'above' }, ], }, }, { id: 'exec-8', phase: 'execution', explanation: 'Prefix array complete! Now we can answer range queries in O(1).', codeLine: 5, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 1, index: 3, state: 'normal' }, { value: 5, index: 4, state: 'normal' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'success' }, { value: 3, index: 1, state: 'success' }, { value: 4, index: 2, state: 'success' }, { value: 8, index: 3, state: 'success' }, { value: 9, index: 4, state: 'success' }, { value: 14, index: 5, state: 'success' }, { value: 23, index: 6, state: 'success' }, ], }, ], pointers: [], variables: [], calculations: [], }, }, // Range query execution { id: 'exec-9', phase: 'execution', explanation: 'Query: sum from index 1 to 4. We need elements [1, 4, 1, 5].', codeLine: 8, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'highlighted' }, { value: 4, index: 2, state: 'highlighted' }, { value: 1, index: 3, state: 'highlighted' }, { value: 5, index: 4, state: 'highlighted' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'normal' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'normal' }, { value: 9, index: 4, state: 'normal' }, { value: 14, index: 5, state: 'normal' }, { value: 23, index: 6, state: 'normal' }, ], }, ], pointers: [ { id: 'i', name: 'i', index: 1, color: 'left' }, { id: 'j', name: 'j', index: 4, color: 'right' }, ], variables: [ { id: 'i', name: 'i', value: 1 }, { id: 'j', name: 'j', value: 4 }, ], calculations: [], }, }, { id: 'exec-10', phase: 'execution', explanation: 'Use formula: prefix[j+1] - prefix[i] = prefix[5] - prefix[1].', codeLine: 8, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'highlighted' }, { value: 4, index: 2, state: 'highlighted' }, { value: 1, index: 3, state: 'highlighted' }, { value: 5, index: 4, state: 'highlighted' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'comparing' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'normal' }, { value: 9, index: 4, state: 'normal' }, { value: 14, index: 5, state: 'comparing' }, { value: 23, index: 6, state: 'normal' }, ], }, ], pointers: [ { id: 'prefix[i]', name: 'prefix[i]', index: 1, color: 'left' }, { id: 'prefix[j+1]', name: 'prefix[j+1]', index: 5, color: 'right' }, ], variables: [ { id: 'i', name: 'i', value: 1 }, { id: 'j', name: 'j', value: 4 }, ], calculations: [], }, }, { id: 'exec-11', phase: 'execution', explanation: 'Calculate: prefix[5] - prefix[1] = 14 - 3 = 11.', codeLine: 8, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'normal' }, { value: 1, index: 1, state: 'success' }, { value: 4, index: 2, state: 'success' }, { value: 1, index: 3, state: 'success' }, { value: 5, index: 4, state: 'success' }, { value: 9, index: 5, state: 'normal' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'normal' }, { value: 3, index: 1, state: 'comparing' }, { value: 4, index: 2, state: 'normal' }, { value: 8, index: 3, state: 'normal' }, { value: 9, index: 4, state: 'normal' }, { value: 14, index: 5, state: 'comparing' }, { value: 23, index: 6, state: 'normal' }, ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 1 }, { id: 'j', name: 'j', value: 4 }, { id: 'result', name: 'result', value: 11, derivation: '14 - 3' }, ], calculations: [ { id: 'calc-7', expression: '14 - 3', result: '11', position: 'above' }, ], }, }, { id: 'exec-12', phase: 'execution', explanation: 'Verify: 1 + 4 + 1 + 5 = 11. Correct! O(n) preprocessing enables O(1) queries.', codeLine: 8, dataState: { arrays: [ { id: 'nums', label: 'Original Array', elements: [ { value: 3, index: 0, state: 'dimmed' }, { value: 1, index: 1, state: 'success' }, { value: 4, index: 2, state: 'success' }, { value: 1, index: 3, state: 'success' }, { value: 5, index: 4, state: 'success' }, { value: 9, index: 5, state: 'dimmed' }, ], }, { id: 'prefix', label: 'Prefix Sum Array', elements: [ { value: 0, index: 0, state: 'dimmed' }, { value: 3, index: 1, state: 'success' }, { value: 4, index: 2, state: 'dimmed' }, { value: 8, index: 3, state: 'dimmed' }, { value: 9, index: 4, state: 'dimmed' }, { value: 14, index: 5, state: 'success' }, { value: 23, index: 6, state: 'dimmed' }, ], }, ], pointers: [], variables: [ { id: 'result', name: 'result', value: 11 }, ], calculations: [ { id: 'calc-8', expression: '1 + 4 + 1 + 5', result: '11', position: 'above' }, ], }, }, ], };