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' },
        ],
      },
    },
  ],
};
