import type { AlgorithmDefinition } from '@/lib/visualizations/types'; // Helper to create a DP cell function dpCell( col: number, value: number | string, state: 'normal' | 'highlighted' | 'comparing' | 'computing' | 'success' | 'dimmed' = 'normal' ) { return { id: `dp-${col}`, value, row: 0, col, state, }; } // Helper to create coins array element function coinElement( index: number, value: number, state: 'normal' | 'highlighted' | 'dimmed' | 'success' | 'comparing' = 'normal' ) { return { value, index, state }; } export const coinChangeAlgorithm: AlgorithmDefinition = { id: 'coin-change', title: 'Coin Change - Dynamic Programming', slug: 'coin-change', pattern: { name: 'Dynamic Programming', description: 'Break down problems into overlapping subproblems and build solutions from optimal substructure.', }, problemStatement: 'Given coins of different denominations and a total amount, find the minimum number of coins needed to make that amount. If it cannot be made, return -1.', intuition: 'For each amount from 1 to target, we compute the minimum coins needed by checking all coin denominations. dp[i] = min coins needed for amount i. For each coin, if coin <= i, we can use it: dp[i] = min(dp[i], dp[i-coin] + 1).', code: { language: 'python', code: `def coin_change(coins: list[int], amount: int) -> int: # Initialize dp with infinity; dp[0] = 0 dp = [float('inf')] * (amount + 1) dp[0] = 0 # Build solution for each amount for i in range(1, amount + 1): for coin in coins: if i - coin >= 0: dp[i] = min(dp[i], dp[i - coin] + 1) return dp[amount] if dp[amount] != float('inf') else -1`, }, initialExample: { input: { coins: [1, 2, 5], amount: 11 }, expected: 3, }, steps: [ // Phase 1: Problem (2 steps) { id: 'problem-1', phase: 'problem', explanation: 'Given coins [1, 2, 5] and amount 11, find the minimum number of coins to make exactly 11.', dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [ { id: 'amount', name: 'amount', value: 11 }, ], calculations: [], }, }, { id: 'problem-2', phase: 'problem', explanation: 'A brute-force approach tries all combinations - exponential time O(S^n). Can we do better by reusing solutions to smaller amounts?', dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [ { id: 'amount', name: 'amount', value: 11 }, ], calculations: [], }, }, // Phase 2: Intuition (4 steps) { id: 'intuition-1', phase: 'intuition', explanation: 'Key insight: If we know the minimum coins for amount 10, we can make 11 with one more coin of value 1. This is optimal substructure.', dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'highlighted'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [ { id: 'amount', name: 'amount', value: 11 }, ], calculations: [ { id: 'calc-1', expression: 'dp[11] = dp[10] + 1', result: '?', position: 'above' }, ], }, }, { id: 'intuition-2', phase: 'intuition', explanation: 'We can also make 11 from amount 9 (using coin 2) or amount 6 (using coin 5). We take the minimum of all options.', dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'comparing'), coinElement(2, 5, 'comparing'), ], }, ], pointers: [], variables: [ { id: 'amount', name: 'amount', value: 11 }, ], calculations: [ { id: 'calc-1', expression: 'min(dp[10]+1, dp[9]+1, dp[6]+1)', result: '?', position: 'above' }, ], }, }, { id: 'intuition-3', phase: 'intuition', explanation: 'Build solutions bottom-up: start from amount 0, compute minimum coins for each amount 1, 2, 3, ... up to target.', dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [], calculations: [], grids: [ { id: 'dp', label: 'DP Table (min coins for each amount)', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, '?'), dpCell(1, '?'), dpCell(2, '?'), dpCell(3, '?'), dpCell(4, '?'), dpCell(5, '?'), dpCell(6, '?'), dpCell(7, '?'), dpCell(8, '?'), dpCell(9, '?'), dpCell(10, '?'), dpCell(11, '?'), ]], }, ], }, }, { id: 'intuition-4', phase: 'intuition', explanation: 'State transition: dp[i] = min(dp[i], dp[i - coin] + 1) for each valid coin. Base case: dp[0] = 0 (zero coins for amount zero).', dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [], calculations: [ { id: 'calc-1', expression: 'dp[i] = min(dp[i], dp[i-coin] + 1)', result: '', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'success'), dpCell(1, '?'), dpCell(2, '?'), dpCell(3, '?'), dpCell(4, '?'), dpCell(5, '?'), dpCell(6, '?'), dpCell(7, '?'), dpCell(8, '?'), dpCell(9, '?'), dpCell(10, '?'), dpCell(11, '?'), ]], }, ], }, }, // Phase 3: Pattern (2 steps) { id: 'pattern-1', phase: 'pattern', explanation: 'Dynamic Programming pattern: Define state (dp[i] = min coins for amount i), identify transition (try each coin), set base case (dp[0] = 0).', dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [ { id: 'state', name: 'State', value: 'dp[i] = min coins' }, ], calculations: [], }, }, { id: 'pattern-2', phase: 'pattern', explanation: 'Time: O(amount * coins), Space: O(amount). Each amount computed once, checking all coins.', dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [ { id: 'time', name: 'Time', value: 'O(amount * coins)' }, { id: 'space', name: 'Space', value: 'O(amount)' }, ], calculations: [], }, }, // Phase 4: Code walkthrough (4 steps) { id: 'code-1', phase: 'code', explanation: 'Initialize dp array with infinity (impossible). dp[0] = 0 because we need 0 coins for amount 0.', codeLine: 3, codeHighlightLines: [2, 3, 4], dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [], calculations: [], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'highlighted'), dpCell(1, '∞'), dpCell(2, '∞'), dpCell(3, '∞'), dpCell(4, '∞'), dpCell(5, '∞'), dpCell(6, '∞'), dpCell(7, '∞'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], }, }, { id: 'code-2', phase: 'code', explanation: 'Outer loop: iterate through amounts 1 to target. For each amount, we compute the minimum coins.', codeLine: 7, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: '1 to amount' }, ], calculations: [], }, }, { id: 'code-3', phase: 'code', explanation: 'Inner loop: try each coin. If coin fits (i - coin >= 0), update dp[i] with minimum.', codeLine: 8, codeHighlightLines: [8, 9, 10], dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'comparing'), coinElement(2, 5, 'comparing'), ], }, ], pointers: [], variables: [], calculations: [ { id: 'calc-1', expression: 'dp[i] = min(dp[i], dp[i-coin] + 1)', result: '', position: 'above' }, ], }, }, { id: 'code-4', phase: 'code', explanation: 'Return dp[amount] if reachable, else -1. Infinity means the amount cannot be made with given coins.', codeLine: 12, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [], calculations: [], }, }, // Phase 5: Execution (~25 steps) // dp[0] = 0 (base case) { id: 'exec-1', phase: 'execution', explanation: 'Initialize: dp[0] = 0 (base case), all others = infinity.', codeLine: 4, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'normal'), coinElement(1, 2, 'normal'), coinElement(2, 5, 'normal'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: '-' }, ], calculations: [], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'success'), dpCell(1, '∞'), dpCell(2, '∞'), dpCell(3, '∞'), dpCell(4, '∞'), dpCell(5, '∞'), dpCell(6, '∞'), dpCell(7, '∞'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], }, }, // Compute dp[1] { id: 'exec-2', phase: 'execution', explanation: 'Compute dp[1]: Try coin 1. dp[1] = min(∞, dp[0] + 1) = min(∞, 1) = 1.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'highlighted'), coinElement(1, 2, 'dimmed'), coinElement(2, 5, 'dimmed'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 1 }, { id: 'coin', name: 'coin', value: 1 }, ], calculations: [ { id: 'calc-1', expression: 'min(∞, dp[0]+1)', result: '1', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'comparing'), dpCell(1, 1, 'computing'), dpCell(2, '∞'), dpCell(3, '∞'), dpCell(4, '∞'), dpCell(5, '∞'), dpCell(6, '∞'), dpCell(7, '∞'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 1, color: 'current' }, { id: 'ptr-dep', name: 'i-1', row: 0, col: 0, color: 'dependency' }, ], }, }, // Compute dp[2] { id: 'exec-3', phase: 'execution', explanation: 'Compute dp[2]: Try coin 1 -> dp[1]+1=2. Try coin 2 -> dp[0]+1=1. dp[2] = min(2, 1) = 1.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'highlighted'), coinElement(2, 5, 'dimmed'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 2 }, { id: 'coin', name: 'coin', value: 2 }, ], calculations: [ { id: 'calc-1', expression: 'min(dp[1]+1, dp[0]+1)', result: '1', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'comparing'), dpCell(1, 1, 'success'), dpCell(2, 1, 'computing'), dpCell(3, '∞'), dpCell(4, '∞'), dpCell(5, '∞'), dpCell(6, '∞'), dpCell(7, '∞'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 2, color: 'current' }, ], }, }, // Compute dp[3] { id: 'exec-4', phase: 'execution', explanation: 'Compute dp[3]: coin 1 -> dp[2]+1=2, coin 2 -> dp[1]+1=2. dp[3] = 2.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'comparing'), coinElement(2, 5, 'dimmed'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 3 }, ], calculations: [ { id: 'calc-1', expression: 'min(dp[2]+1, dp[1]+1)', result: '2', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'normal'), dpCell(1, 1, 'comparing'), dpCell(2, 1, 'comparing'), dpCell(3, 2, 'computing'), dpCell(4, '∞'), dpCell(5, '∞'), dpCell(6, '∞'), dpCell(7, '∞'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 3, color: 'current' }, ], }, }, // Compute dp[4] { id: 'exec-5', phase: 'execution', explanation: 'Compute dp[4]: coin 1 -> dp[3]+1=3, coin 2 -> dp[2]+1=2. dp[4] = 2.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'highlighted'), coinElement(2, 5, 'dimmed'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 4 }, ], calculations: [ { id: 'calc-1', expression: 'min(dp[3]+1, dp[2]+1)', result: '2', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'normal'), dpCell(1, 1, 'normal'), dpCell(2, 1, 'comparing'), dpCell(3, 2, 'success'), dpCell(4, 2, 'computing'), dpCell(5, '∞'), dpCell(6, '∞'), dpCell(7, '∞'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 4, color: 'current' }, ], }, }, // Compute dp[5] - First time using coin 5! { id: 'exec-6', phase: 'execution', explanation: 'Compute dp[5]: coin 1 -> 3, coin 2 -> 3, coin 5 -> dp[0]+1=1. dp[5] = 1!', codeLine: 10, decision: { question: 'Which coin gives minimum?', answer: 'Coin 5: dp[0]+1 = 1', action: 'Use one coin of 5', }, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'comparing'), coinElement(2, 5, 'highlighted'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 5 }, ], calculations: [ { id: 'calc-1', expression: 'min(3, 3, dp[0]+1)', result: '1', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'comparing'), dpCell(1, 1, 'normal'), dpCell(2, 1, 'normal'), dpCell(3, 2, 'normal'), dpCell(4, 2, 'success'), dpCell(5, 1, 'computing'), dpCell(6, '∞'), dpCell(7, '∞'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 5, color: 'current' }, { id: 'ptr-dep', name: 'i-5', row: 0, col: 0, color: 'dependency' }, ], }, }, // Compute dp[6] { id: 'exec-7', phase: 'execution', explanation: 'Compute dp[6]: coin 1 -> dp[5]+1=2, coin 2 -> dp[4]+1=3, coin 5 -> dp[1]+1=2. dp[6] = 2.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'highlighted'), coinElement(1, 2, 'comparing'), coinElement(2, 5, 'comparing'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 6 }, ], calculations: [ { id: 'calc-1', expression: 'min(dp[5]+1, dp[4]+1, dp[1]+1)', result: '2', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'normal'), dpCell(1, 1, 'comparing'), dpCell(2, 1, 'normal'), dpCell(3, 2, 'normal'), dpCell(4, 2, 'comparing'), dpCell(5, 1, 'comparing'), dpCell(6, 2, 'computing'), dpCell(7, '∞'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 6, color: 'current' }, ], }, }, // Compute dp[7] { id: 'exec-8', phase: 'execution', explanation: 'Compute dp[7]: coin 1 -> 3, coin 2 -> dp[5]+1=2, coin 5 -> dp[2]+1=2. dp[7] = 2.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'highlighted'), coinElement(2, 5, 'highlighted'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 7 }, ], calculations: [ { id: 'calc-1', expression: 'min(3, dp[5]+1, dp[2]+1)', result: '2', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'normal'), dpCell(1, 1, 'normal'), dpCell(2, 1, 'comparing'), dpCell(3, 2, 'normal'), dpCell(4, 2, 'normal'), dpCell(5, 1, 'comparing'), dpCell(6, 2, 'success'), dpCell(7, 2, 'computing'), dpCell(8, '∞'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 7, color: 'current' }, ], }, }, // Compute dp[8] { id: 'exec-9', phase: 'execution', explanation: 'Compute dp[8]: coin 1 -> 3, coin 2 -> 3, coin 5 -> dp[3]+1=3. dp[8] = 3.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'comparing'), coinElement(2, 5, 'comparing'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 8 }, ], calculations: [ { id: 'calc-1', expression: 'min(dp[7]+1, dp[6]+1, dp[3]+1)', result: '3', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'normal'), dpCell(1, 1, 'normal'), dpCell(2, 1, 'normal'), dpCell(3, 2, 'comparing'), dpCell(4, 2, 'normal'), dpCell(5, 1, 'normal'), dpCell(6, 2, 'comparing'), dpCell(7, 2, 'comparing'), dpCell(8, 3, 'computing'), dpCell(9, '∞'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 8, color: 'current' }, ], }, }, // Compute dp[9] { id: 'exec-10', phase: 'execution', explanation: 'Compute dp[9]: coin 1 -> 4, coin 2 -> dp[7]+1=3, coin 5 -> dp[4]+1=3. dp[9] = 3.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'highlighted'), coinElement(2, 5, 'highlighted'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 9 }, ], calculations: [ { id: 'calc-1', expression: 'min(4, dp[7]+1, dp[4]+1)', result: '3', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'normal'), dpCell(1, 1, 'normal'), dpCell(2, 1, 'normal'), dpCell(3, 2, 'normal'), dpCell(4, 2, 'comparing'), dpCell(5, 1, 'normal'), dpCell(6, 2, 'normal'), dpCell(7, 2, 'comparing'), dpCell(8, 3, 'success'), dpCell(9, 3, 'computing'), dpCell(10, '∞'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 9, color: 'current' }, ], }, }, // Compute dp[10] { id: 'exec-11', phase: 'execution', explanation: 'Compute dp[10]: coin 1 -> 4, coin 2 -> 4, coin 5 -> dp[5]+1=2. dp[10] = 2!', codeLine: 10, decision: { question: 'Which coin gives minimum?', answer: 'Coin 5: dp[5]+1 = 2', action: 'Two coins of 5', }, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'comparing'), coinElement(1, 2, 'comparing'), coinElement(2, 5, 'highlighted'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 10 }, ], calculations: [ { id: 'calc-1', expression: 'min(4, 4, dp[5]+1)', result: '2', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'normal'), dpCell(1, 1, 'normal'), dpCell(2, 1, 'normal'), dpCell(3, 2, 'normal'), dpCell(4, 2, 'normal'), dpCell(5, 1, 'comparing'), dpCell(6, 2, 'normal'), dpCell(7, 2, 'normal'), dpCell(8, 3, 'normal'), dpCell(9, 3, 'success'), dpCell(10, 2, 'computing'), dpCell(11, '∞'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 10, color: 'current' }, { id: 'ptr-dep', name: 'i-5', row: 0, col: 5, color: 'dependency' }, ], }, }, // Compute dp[11] - The answer! { id: 'exec-12', phase: 'execution', explanation: 'Compute dp[11]: coin 1 -> dp[10]+1=3, coin 2 -> dp[9]+1=4, coin 5 -> dp[6]+1=3. dp[11] = 3.', codeLine: 10, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'highlighted'), coinElement(1, 2, 'comparing'), coinElement(2, 5, 'highlighted'), ], }, ], pointers: [], variables: [ { id: 'i', name: 'i', value: 11 }, ], calculations: [ { id: 'calc-1', expression: 'min(dp[10]+1, dp[9]+1, dp[6]+1)', result: '3', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'normal'), dpCell(1, 1, 'normal'), dpCell(2, 1, 'normal'), dpCell(3, 2, 'normal'), dpCell(4, 2, 'normal'), dpCell(5, 1, 'normal'), dpCell(6, 2, 'comparing'), dpCell(7, 2, 'normal'), dpCell(8, 3, 'normal'), dpCell(9, 3, 'comparing'), dpCell(10, 2, 'comparing'), dpCell(11, 3, 'computing'), ]], }, ], gridPointers: [ { id: 'ptr-i', name: 'i', row: 0, col: 11, color: 'current' }, ], }, }, // Final result { id: 'exec-13', phase: 'execution', explanation: 'Complete! dp[11] = 3. We need minimum 3 coins: 5 + 5 + 1 = 11.', codeLine: 12, dataState: { arrays: [ { id: 'coins', label: 'Coins', elements: [ coinElement(0, 1, 'success'), coinElement(1, 2, 'dimmed'), coinElement(2, 5, 'success'), ], }, ], pointers: [], variables: [ { id: 'result', name: 'result', value: 3, derivation: '5 + 5 + 1 = 11' }, ], calculations: [ { id: 'calc-1', expression: '5 + 5 + 1', result: '11', position: 'above' }, ], grids: [ { id: 'dp', label: 'DP Table', colLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], cells: [[ dpCell(0, 0, 'success'), dpCell(1, 1, 'success'), dpCell(2, 1, 'success'), dpCell(3, 2, 'success'), dpCell(4, 2, 'success'), dpCell(5, 1, 'success'), dpCell(6, 2, 'success'), dpCell(7, 2, 'success'), dpCell(8, 3, 'success'), dpCell(9, 3, 'success'), dpCell(10, 2, 'success'), dpCell(11, 3, 'highlighted'), ]], }, ], gridPointers: [ { id: 'ptr-result', name: 'answer', row: 0, col: 11, color: 'result' }, ], }, }, ], };