import type { AlgorithmDefinition, DecisionNodeState, DecisionTreeState } from '@/lib/visualizations/types';

/**
 * Decision tree for Subsets problem with nums = [1, 2, 3]:
 *
 *                         []
 *                       /    \
 *                    [1]      []
 *                   /  \     /  \
 *               [1,2]  [1] [2]   []
 *               /  \   / \  / \   / \
 *          [1,2,3] [1,2] [1,3] [1] [2,3] [2] [3] []
 *
 * Each level represents: Include element i?
 * Left branch = include, Right branch = exclude
 * Leaf nodes are the 8 subsets (2^3)
 */

// Node IDs for the decision tree
const ROOT = 'root';
const L1_INC = 'l1-inc'; // [1]
const L1_EXC = 'l1-exc'; // []
const L2_INC_INC = 'l2-inc-inc'; // [1,2]
const L2_INC_EXC = 'l2-inc-exc'; // [1]
const L2_EXC_INC = 'l2-exc-inc'; // [2]
const L2_EXC_EXC = 'l2-exc-exc'; // []
const L3_123 = 'l3-123'; // [1,2,3]
const L3_12 = 'l3-12'; // [1,2]
const L3_13 = 'l3-13'; // [1,3]
const L3_1 = 'l3-1'; // [1]
const L3_23 = 'l3-23'; // [2,3]
const L3_2 = 'l3-2'; // [2]
const L3_3 = 'l3-3'; // [3]
const L3_EMPTY = 'l3-empty'; // []

type NodeStateType = DecisionNodeState['state'];

// Helper to create decision tree state
function createDecisionTree(
  nodeStates: Record<string, NodeStateType>,
  decisions: Record<string, string>,
  currentPath: string[] = []
): DecisionTreeState {
  const getState = (id: string): NodeStateType => nodeStates[id] ?? 'normal';
  const getDecision = (id: string): string | undefined => decisions[id];

  const nodes: DecisionNodeState[] = [
    { id: ROOT, value: '[]', state: getState(ROOT), left: L1_INC, right: L1_EXC, decision: getDecision(ROOT), depth: 0 },
    { id: L1_INC, value: '[1]', state: getState(L1_INC), left: L2_INC_INC, right: L2_INC_EXC, decision: getDecision(L1_INC), depth: 1 },
    { id: L1_EXC, value: '[]', state: getState(L1_EXC), left: L2_EXC_INC, right: L2_EXC_EXC, decision: getDecision(L1_EXC), depth: 1 },
    { id: L2_INC_INC, value: '[1,2]', state: getState(L2_INC_INC), left: L3_123, right: L3_12, decision: getDecision(L2_INC_INC), depth: 2 },
    { id: L2_INC_EXC, value: '[1]', state: getState(L2_INC_EXC), left: L3_13, right: L3_1, decision: getDecision(L2_INC_EXC), depth: 2 },
    { id: L2_EXC_INC, value: '[2]', state: getState(L2_EXC_INC), left: L3_23, right: L3_2, decision: getDecision(L2_EXC_INC), depth: 2 },
    { id: L2_EXC_EXC, value: '[]', state: getState(L2_EXC_EXC), left: L3_3, right: L3_EMPTY, decision: getDecision(L2_EXC_EXC), depth: 2 },
    { id: L3_123, value: '[1,2,3]', state: getState(L3_123), left: null, right: null, depth: 3 },
    { id: L3_12, value: '[1,2]', state: getState(L3_12), left: null, right: null, depth: 3 },
    { id: L3_13, value: '[1,3]', state: getState(L3_13), left: null, right: null, depth: 3 },
    { id: L3_1, value: '[1]', state: getState(L3_1), left: null, right: null, depth: 3 },
    { id: L3_23, value: '[2,3]', state: getState(L3_23), left: null, right: null, depth: 3 },
    { id: L3_2, value: '[2]', state: getState(L3_2), left: null, right: null, depth: 3 },
    { id: L3_3, value: '[3]', state: getState(L3_3), left: null, right: null, depth: 3 },
    { id: L3_EMPTY, value: '[]', state: getState(L3_EMPTY), left: null, right: null, depth: 3 },
  ];

  return {
    id: 'decision-tree',
    label: 'Decision Tree',
    rootId: ROOT,
    nodes,
    currentPath,
  };
}

export const subsetsAlgorithm: AlgorithmDefinition = {
  id: 'subsets',
  title: 'Subsets (Backtracking)',
  slug: 'subsets',
  pattern: {
    name: 'Backtracking',
    description:
      'Build solutions incrementally using Choose-Explore-Unchoose pattern, exploring all possibilities through a decision tree.',
  },
  problemStatement:
    'Given an array nums of unique integers, return all possible subsets (the power set). The solution set must not contain duplicate subsets.',
  intuition:
    'Every subset is built by making a binary decision for each element: include it or exclude it. This creates a decision tree with 2^n leaves, each representing one unique subset.',
  code: {
    language: 'python',
    code: `def subsets(nums: list[int]) -> list[list[int]]:
    result = []

    def backtrack(start: int, current: list[int]):
        # Add current subset to result
        result.append(current[:])

        # Try including each remaining element
        for i in range(start, len(nums)):
            current.append(nums[i])      # Choose
            backtrack(i + 1, current)    # Explore
            current.pop()                # Unchoose

    backtrack(0, [])
    return result`,
  },
  initialExample: {
    input: { nums: [1, 2, 3] },
    expected: [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]],
  },
  steps: [
    // ==========================================
    // Phase 1: Problem (2 steps)
    // ==========================================
    {
      id: 'problem-1',
      phase: 'problem',
      explanation:
        'Given nums = [1, 2, 3], find all possible subsets. A subset can include any combination of elements, including the empty set.',
      dataState: {
        arrays: [{
          id: 'input',
          label: 'Input Array',
          elements: [
            { value: 1, index: 0, state: 'normal' },
            { value: 2, index: 1, state: 'normal' },
            { value: 3, index: 2, state: 'normal' },
          ],
        }],
        pointers: [],
        variables: [],
        calculations: [],
        decisionTrees: [createDecisionTree({}, {})],
      },
    },
    {
      id: 'problem-2',
      phase: 'problem',
      explanation:
        'With 3 elements, there are 2^3 = 8 possible subsets. Each element can be included or excluded independently.',
      dataState: {
        arrays: [{
          id: 'input',
          label: 'Input Array',
          elements: [
            { value: 1, index: 0, state: 'highlighted' },
            { value: 2, index: 1, state: 'highlighted' },
            { value: 3, index: 2, state: 'highlighted' },
          ],
        }],
        pointers: [],
        variables: [
          { id: 'total', name: 'Total subsets', value: '2³ = 8' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree({}, {})],
      },
    },

    // ==========================================
    // Phase 2: Intuition (3 steps)
    // ==========================================
    {
      id: 'intuition-1',
      phase: 'intuition',
      explanation:
        'Think of building each subset as a series of binary decisions: for each element, we ask "Include it?" Yes (left branch) or No (right branch).',
      dataState: {
        arrays: [],
        pointers: [],
        variables: [],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'current' },
          { [ROOT]: 'Include 1?' }
        )],
      },
    },
    {
      id: 'intuition-2',
      phase: 'intuition',
      explanation:
        'This creates a binary decision tree. Each path from root to leaf represents one subset. Left = include the element, Right = exclude it.',
      dataState: {
        arrays: [],
        pointers: [],
        variables: [],
        calculations: [],
        decisionTrees: [createDecisionTree(
          {
            [ROOT]: 'exploring',
            [L1_INC]: 'exploring',
            [L2_INC_INC]: 'exploring',
            [L3_123]: 'current',
          },
          {},
          [ROOT, L1_INC, L2_INC_INC, L3_123]
        )],
      },
    },
    {
      id: 'intuition-3',
      phase: 'intuition',
      explanation:
        'The tree has depth n (3 levels of decisions) and 2^n = 8 leaf nodes. Each leaf is a complete subset we add to our result.',
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'depth', name: 'Tree depth', value: 'n = 3' },
          { id: 'leaves', name: 'Leaf nodes', value: '2ⁿ = 8' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          {
            [L3_123]: 'complete',
            [L3_12]: 'complete',
            [L3_13]: 'complete',
            [L3_1]: 'complete',
            [L3_23]: 'complete',
            [L3_2]: 'complete',
            [L3_3]: 'complete',
            [L3_EMPTY]: 'complete',
          },
          {}
        )],
      },
    },

    // ==========================================
    // Phase 3: Pattern (2 steps)
    // ==========================================
    {
      id: 'pattern-1',
      phase: 'pattern',
      explanation:
        'Backtracking follows the Choose-Explore-Unchoose pattern: (1) Choose an element, (2) Explore with it, (3) Unchoose to try other paths.',
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'step1', name: 'Choose', value: 'current.append(x)' },
          { id: 'step2', name: 'Explore', value: 'backtrack(...)' },
          { id: 'step3', name: 'Unchoose', value: 'current.pop()' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree({}, {})],
      },
    },
    {
      id: 'pattern-2',
      phase: 'pattern',
      explanation:
        'We add each partial result at every node (not just leaves). This captures all subsets: [], [1], [1,2], [1,2,3], [1,3], [2], [2,3], [3].',
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'key', name: 'Key insight', value: 'Add result at each node' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree({}, {})],
      },
    },

    // ==========================================
    // Phase 4: Code (3 steps)
    // ==========================================
    {
      id: 'code-1',
      phase: 'code',
      explanation:
        'Initialize: empty result list. The backtrack function takes start index (which elements to consider) and current subset being built.',
      codeLine: 2,
      codeHighlightLines: [2, 4],
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[]' },
          { id: 'start', name: 'start', value: '0' },
          { id: 'current', name: 'current', value: '[]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree({ [ROOT]: 'current' }, {})],
      },
    },
    {
      id: 'code-2',
      phase: 'code',
      explanation:
        'First action: always add current subset to result (using a copy). This captures the subset at this point in the decision tree.',
      codeLine: 6,
      codeHighlightLines: [6],
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[]]' },
          { id: 'current', name: 'current', value: '[]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree({ [ROOT]: 'current' }, {})],
      },
    },
    {
      id: 'code-3',
      phase: 'code',
      explanation:
        'For each remaining element: Choose (append), Explore (recurse with start + 1), Unchoose (pop). This builds all combinations.',
      codeLine: 9,
      codeHighlightLines: [9, 10, 11, 12],
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'loop', name: 'Loop', value: 'for i in range(start, len(nums))' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'current' },
          { [L1_INC]: 'Include 2?' },
          [ROOT, L1_INC]
        )],
      },
    },

    // ==========================================
    // Phase 5: Execution (~20 steps)
    // ==========================================
    {
      id: 'exec-1',
      phase: 'execution',
      explanation:
        'Start: backtrack(0, []). At the root node, first add [] to result.',
      codeLine: 6,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[]]' },
          { id: 'current', name: 'current', value: '[]' },
          { id: 'start', name: 'start', value: '0' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'current' },
          { [ROOT]: 'Include 1?' },
          [ROOT]
        )],
      },
    },
    {
      id: 'exec-2',
      phase: 'execution',
      explanation:
        'Choose: append 1 to current. Now current = [1]. This is the "include 1" branch.',
      codeLine: 10,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[]]' },
          { id: 'current', name: 'current', value: '[1]', previousValue: '[]' },
          { id: 'i', name: 'i', value: '0 (element: 1)' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'current' },
          { [L1_INC]: 'Include 2?' },
          [ROOT, L1_INC]
        )],
      },
    },
    {
      id: 'exec-3',
      phase: 'execution',
      explanation:
        'Explore: backtrack(1, [1]). At this node, add [1] to result. Result: [[], [1]].',
      codeLine: 6,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1]]' },
          { id: 'current', name: 'current', value: '[1]' },
          { id: 'start', name: 'start', value: '1' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'current' },
          { [L1_INC]: 'Include 2?' },
          [ROOT, L1_INC]
        )],
      },
    },
    {
      id: 'exec-4',
      phase: 'execution',
      explanation:
        'Choose: append 2 to current. Now current = [1, 2]. Taking the "include 2" branch.',
      codeLine: 10,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1]]' },
          { id: 'current', name: 'current', value: '[1, 2]', previousValue: '[1]' },
          { id: 'i', name: 'i', value: '1 (element: 2)' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'exploring', [L2_INC_INC]: 'current' },
          { [L2_INC_INC]: 'Include 3?' },
          [ROOT, L1_INC, L2_INC_INC]
        )],
      },
    },
    {
      id: 'exec-5',
      phase: 'execution',
      explanation:
        'Explore: backtrack(2, [1, 2]). Add [1, 2] to result. Result: [[], [1], [1, 2]].',
      codeLine: 6,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2]]' },
          { id: 'current', name: 'current', value: '[1, 2]' },
          { id: 'start', name: 'start', value: '2' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'exploring', [L2_INC_INC]: 'current' },
          { [L2_INC_INC]: 'Include 3?' },
          [ROOT, L1_INC, L2_INC_INC]
        )],
      },
    },
    {
      id: 'exec-6',
      phase: 'execution',
      explanation:
        'Choose: append 3. current = [1, 2, 3]. We\'ve reached the deepest left path.',
      codeLine: 10,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2]]' },
          { id: 'current', name: 'current', value: '[1, 2, 3]', previousValue: '[1, 2]' },
          { id: 'i', name: 'i', value: '2 (element: 3)' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'exploring', [L2_INC_INC]: 'exploring', [L3_123]: 'current' },
          {},
          [ROOT, L1_INC, L2_INC_INC, L3_123]
        )],
      },
    },
    {
      id: 'exec-7',
      phase: 'execution',
      explanation:
        'Explore: backtrack(3, [1, 2, 3]). Add [1, 2, 3] to result. No more elements (start=3 >= len=3).',
      codeLine: 6,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3]]' },
          { id: 'current', name: 'current', value: '[1, 2, 3]' },
          { id: 'start', name: 'start', value: '3' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'exploring', [L2_INC_INC]: 'exploring', [L3_123]: 'complete' },
          {},
          [ROOT, L1_INC, L2_INC_INC, L3_123]
        )],
      },
    },
    {
      id: 'exec-8',
      phase: 'execution',
      explanation:
        'Backtrack: pop 3 from current. current = [1, 2]. Return to [1, 2] node. Loop ends (no more elements).',
      codeLine: 12,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3]]' },
          { id: 'current', name: 'current', value: '[1, 2]', previousValue: '[1, 2, 3]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'exploring', [L2_INC_INC]: 'backtracking', [L3_123]: 'complete', [L3_12]: 'complete' },
          {},
          [ROOT, L1_INC, L2_INC_INC]
        )],
      },
    },
    {
      id: 'exec-9',
      phase: 'execution',
      explanation:
        'Backtrack: pop 2 from current. current = [1]. Back at [1] node. Continue loop with i=2 (element 3).',
      codeLine: 12,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3]]' },
          { id: 'current', name: 'current', value: '[1]', previousValue: '[1, 2]' },
          { id: 'i', name: 'i', value: '2 (element: 3)' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'backtracking', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'current', [L3_123]: 'complete', [L3_12]: 'complete' },
          { [L2_INC_EXC]: 'Include 3?' },
          [ROOT, L1_INC, L2_INC_EXC]
        )],
      },
    },
    {
      id: 'exec-10',
      phase: 'execution',
      explanation:
        'Choose: append 3. current = [1, 3]. This is the path: include 1, skip 2, include 3.',
      codeLine: 10,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3]]' },
          { id: 'current', name: 'current', value: '[1, 3]', previousValue: '[1]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'exploring', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'exploring', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'current' },
          {},
          [ROOT, L1_INC, L2_INC_EXC, L3_13]
        )],
      },
    },
    {
      id: 'exec-11',
      phase: 'execution',
      explanation:
        'Explore: backtrack(3, [1, 3]). Add [1, 3] to result. Result: [[], [1], [1, 2], [1, 2, 3], [1, 3]].',
      codeLine: 6,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3]]' },
          { id: 'current', name: 'current', value: '[1, 3]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'exploring', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'exploring', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete' },
          {},
          [ROOT, L1_INC, L2_INC_EXC, L3_13]
        )],
      },
    },
    {
      id: 'exec-12',
      phase: 'execution',
      explanation:
        'Backtrack: pop 3, then pop 1. Back to root. Now try i=1 (element 2), skipping 1.',
      codeLine: 12,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3]]' },
          { id: 'current', name: 'current', value: '[]', previousValue: '[1]' },
          { id: 'i', name: 'i', value: '1 (element: 2)' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'backtracking', [L1_INC]: 'complete', [L1_EXC]: 'current', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete' },
          { [L1_EXC]: 'Include 2?' },
          [ROOT, L1_EXC]
        )],
      },
    },
    {
      id: 'exec-13',
      phase: 'execution',
      explanation:
        'Choose: append 2. current = [2]. Path: skip 1, include 2.',
      codeLine: 10,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3]]' },
          { id: 'current', name: 'current', value: '[2]', previousValue: '[]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'complete', [L1_EXC]: 'exploring', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L2_EXC_INC]: 'current', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete' },
          { [L2_EXC_INC]: 'Include 3?' },
          [ROOT, L1_EXC, L2_EXC_INC]
        )],
      },
    },
    {
      id: 'exec-14',
      phase: 'execution',
      explanation:
        'Explore: backtrack(2, [2]). Add [2] to result. Result: [[], [1], [1, 2], [1, 2, 3], [1, 3], [2]].',
      codeLine: 6,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3], [2]]' },
          { id: 'current', name: 'current', value: '[2]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'complete', [L1_EXC]: 'exploring', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L2_EXC_INC]: 'current', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete' },
          { [L2_EXC_INC]: 'Include 3?' },
          [ROOT, L1_EXC, L2_EXC_INC]
        )],
      },
    },
    {
      id: 'exec-15',
      phase: 'execution',
      explanation:
        'Choose: append 3. current = [2, 3]. Explore and add to result. Result: [..., [2, 3]].',
      codeLine: 10,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3]]' },
          { id: 'current', name: 'current', value: '[2, 3]', previousValue: '[2]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'complete', [L1_EXC]: 'exploring', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L2_EXC_INC]: 'exploring', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete', [L3_23]: 'complete', [L3_2]: 'complete' },
          {},
          [ROOT, L1_EXC, L2_EXC_INC, L3_23]
        )],
      },
    },
    {
      id: 'exec-16',
      phase: 'execution',
      explanation:
        'Backtrack to root. Now try i=2 (element 3), skipping both 1 and 2.',
      codeLine: 12,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3]]' },
          { id: 'current', name: 'current', value: '[]', previousValue: '[2]' },
          { id: 'i', name: 'i', value: '2 (element: 3)' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'backtracking', [L1_INC]: 'complete', [L1_EXC]: 'complete', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L2_EXC_INC]: 'complete', [L2_EXC_EXC]: 'current', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete', [L3_23]: 'complete', [L3_2]: 'complete' },
          { [L2_EXC_EXC]: 'Include 3?' },
          [ROOT, L1_EXC, L2_EXC_EXC]
        )],
      },
    },
    {
      id: 'exec-17',
      phase: 'execution',
      explanation:
        'Choose: append 3. current = [3]. Path: skip 1, skip 2, include 3.',
      codeLine: 10,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3]]' },
          { id: 'current', name: 'current', value: '[3]', previousValue: '[]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'complete', [L1_EXC]: 'exploring', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L2_EXC_INC]: 'complete', [L2_EXC_EXC]: 'exploring', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete', [L3_23]: 'complete', [L3_2]: 'complete', [L3_3]: 'current' },
          {},
          [ROOT, L1_EXC, L2_EXC_EXC, L3_3]
        )],
      },
    },
    {
      id: 'exec-18',
      phase: 'execution',
      explanation:
        'Explore: backtrack(3, [3]). Add [3] to result. Result: [..., [3]].',
      codeLine: 6,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]' },
          { id: 'current', name: 'current', value: '[3]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          { [ROOT]: 'exploring', [L1_INC]: 'complete', [L1_EXC]: 'exploring', [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L2_EXC_INC]: 'complete', [L2_EXC_EXC]: 'exploring', [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete', [L3_23]: 'complete', [L3_2]: 'complete', [L3_3]: 'complete', [L3_EMPTY]: 'complete' },
          {},
          [ROOT, L1_EXC, L2_EXC_EXC, L3_3]
        )],
      },
    },
    {
      id: 'exec-19',
      phase: 'execution',
      explanation:
        'Backtrack all the way to root. Loop at root ends (i=3 >= len=3). All paths explored.',
      codeLine: 12,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]' },
          { id: 'current', name: 'current', value: '[]', previousValue: '[3]' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          {
            [ROOT]: 'complete',
            [L1_INC]: 'complete', [L1_EXC]: 'complete',
            [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L2_EXC_INC]: 'complete', [L2_EXC_EXC]: 'complete',
            [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete',
            [L3_23]: 'complete', [L3_2]: 'complete', [L3_3]: 'complete', [L3_EMPTY]: 'complete',
          },
          {},
          []
        )],
      },
    },
    {
      id: 'exec-20',
      phase: 'execution',
      explanation:
        'Done! Return result with all 8 subsets: [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]].',
      codeLine: 15,
      dataState: {
        arrays: [],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: '8 subsets found' },
        ],
        calculations: [],
        decisionTrees: [createDecisionTree(
          {
            [ROOT]: 'complete',
            [L1_INC]: 'complete', [L1_EXC]: 'complete',
            [L2_INC_INC]: 'complete', [L2_INC_EXC]: 'complete', [L2_EXC_INC]: 'complete', [L2_EXC_EXC]: 'complete',
            [L3_123]: 'complete', [L3_12]: 'complete', [L3_13]: 'complete', [L3_1]: 'complete',
            [L3_23]: 'complete', [L3_2]: 'complete', [L3_3]: 'complete', [L3_EMPTY]: 'complete',
          },
          {},
          []
        )],
      },
    },
  ],
};
