All files / web/src/app/create/worksheets problemAnalysis.ts

100% Statements 155/155
88.88% Branches 8/9
100% Functions 2/2
100% Lines 155/155

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 1561x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 120x 120x 15x 15x 120x 105x 105x 120x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 20x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 24x 24x 24x 24x 4x 4x 24x 20x 20x 24x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x  
// Problem analysis for conditional display rules
// Analyzes n-digit + p-digit addition problems to determine characteristics
// Supports 1-5 digit problems (max sum: 99999 + 99999 = 199998)
 
export type PlaceValue =
  | 'ones'
  | 'tens'
  | 'hundreds'
  | 'thousands'
  | 'tenThousands'
  | 'hundredThousands'
 
export interface ProblemMeta {
  a: number
  b: number
  digitsA: number
  digitsB: number
  maxDigits: number
  sum: number
  digitsSum: number
  requiresRegrouping: boolean
  regroupCount: number
  regroupPlaces: PlaceValue[]
}
 
/**
 * Analyze an addition problem to determine its characteristics
 * Supports 1-5 digit problems (a and b can each be 1-99999)
 * Maximum sum: 99999 + 99999 = 199998 (6 digits)
 */
export function analyzeProblem(a: number, b: number): ProblemMeta {
  // Basic properties
  const digitsA = a.toString().length
  const digitsB = b.toString().length
  const maxDigits = Math.max(digitsA, digitsB)
  const sum = a + b
  const digitsSum = sum.toString().length
 
  // Analyze regrouping place by place
  // Pad to 6 digits for consistent indexing (supports up to 99999 + 99999 = 199998)
  const aDigits = String(a).padStart(6, '0').split('').map(Number).reverse()
  const bDigits = String(b).padStart(6, '0').split('').map(Number).reverse()
 
  const regroupPlaces: PlaceValue[] = []
  const places: PlaceValue[] = [
    'ones',
    'tens',
    'hundreds',
    'thousands',
    'tenThousands',
    'hundredThousands',
  ]
 
  // Check each place value for carrying
  // We need to track carries propagating through place values
  let carry = 0
  for (let i = 0; i < 6; i++) {
    const digitSum = aDigits[i] + bDigits[i] + carry
    if (digitSum >= 10) {
      regroupPlaces.push(places[i])
      carry = 1
    } else {
      carry = 0
    }
  }
 
  return {
    a,
    b,
    digitsA,
    digitsB,
    maxDigits,
    sum,
    digitsSum,
    requiresRegrouping: regroupPlaces.length > 0,
    regroupCount: regroupPlaces.length,
    regroupPlaces,
  }
}
 
/**
 * Metadata for a subtraction problem
 */
export interface SubtractionProblemMeta {
  minuend: number
  subtrahend: number
  digitsMinuend: number
  digitsSubtrahend: number
  maxDigits: number
  difference: number
  digitsDifference: number
  requiresBorrowing: boolean
  borrowCount: number
  borrowPlaces: PlaceValue[]
}
 
/**
 * Analyze a subtraction problem to determine its characteristics
 * Supports 1-5 digit problems (minuend and subtrahend can each be 1-99999)
 * Assumes minuend >= subtrahend (no negative results)
 */
export function analyzeSubtractionProblem(
  minuend: number,
  subtrahend: number
): SubtractionProblemMeta {
  // Basic properties
  const digitsMinuend = minuend.toString().length
  const digitsSubtrahend = subtrahend.toString().length
  const maxDigits = Math.max(digitsMinuend, digitsSubtrahend)
  const difference = minuend - subtrahend
  const digitsDifference = difference === 0 ? 1 : difference.toString().length
 
  // Analyze borrowing place by place
  // Pad to 6 digits for consistent indexing
  const mDigits = String(minuend).padStart(6, '0').split('').map(Number).reverse()
  const sDigits = String(subtrahend).padStart(6, '0').split('').map(Number).reverse()
 
  const borrowPlaces: PlaceValue[] = []
  const places: PlaceValue[] = [
    'ones',
    'tens',
    'hundreds',
    'thousands',
    'tenThousands',
    'hundredThousands',
  ]
 
  // Check each place value for borrowing
  // We need to track borrows propagating through place values
  let borrow = 0
  for (let i = 0; i < 6; i++) {
    const mDigit = mDigits[i] - borrow
    const sDigit = sDigits[i]
 
    if (mDigit < sDigit) {
      borrowPlaces.push(places[i])
      borrow = 1 // Need to borrow from next higher place
    } else {
      borrow = 0
    }
  }
 
  return {
    minuend,
    subtrahend,
    digitsMinuend,
    digitsSubtrahend,
    maxDigits,
    difference,
    digitsDifference,
    requiresBorrowing: borrowPlaces.length > 0,
    borrowCount: borrowPlaces.length,
    borrowPlaces,
  }
}