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 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 27x 27x 27x 27x 27x 2x 2x | /**
* Complexity Budget Configuration
*
* Controls the "cognitive load budget" system that ensures problems
* are appropriately challenging for each student's skill level.
*
* Budget = Σ(baseCost × masteryMultiplier) per term
*
* A term's cost reflects how hard it is for THIS student:
* - Practiced ten complements: +9 costs 6 (base 2 × practicing 3)
* - Unpracticed ten complements: +9 costs 8 (base 2 × not_practicing 4)
*/
import type { SessionPartType } from '@/db/schema/session-plans'
// =============================================================================
// General Budget Defaults
// =============================================================================
/**
* Default complexity budgets for common scenarios.
* Used when no specific purpose/part constraints apply.
*/
export const DEFAULT_COMPLEXITY_BUDGETS = {
/** No limit - full complexity allowed */
unlimited: Number.POSITIVE_INFINITY,
/** Use abacus mode - high budget (physical abacus reduces cognitive load) */
useAbacus: 12,
/** Visualization beginner - conservative */
visualizationDefault: 6,
/** Linear mode */
linearDefault: 8,
} as const
// =============================================================================
// Per-Purpose, Per-Part Complexity Bounds
// =============================================================================
/**
* Complexity bounds per purpose and part type.
*
* Each slot purpose can have different min/max complexity requirements.
* null = no constraint (unlimited)
*
* - min: Minimum cost per term (ensures terms aren't trivial)
* - max: Maximum cost per term (caps cognitive load)
*
* Example scenarios:
* - focus/visualization max:3 = cap complexity for mental math
* - challenge min:1 = every term must use at least one five-complement
*/
/**
* Complexity bounds per purpose and part type.
*
* Each slot purpose can have different min/max complexity requirements.
* null = no constraint (unlimited)
*
* - min: Minimum cost per term (ensures terms aren't trivial)
* - max: Maximum cost per term (caps cognitive load)
*
* The max budget interacts with BKT multipliers:
* - Adaptive-BKT mode: weak skills have high multipliers (up to 4x), so their terms
* are more likely to exceed max budget and be filtered out
* - Classic/Adaptive mode: uses discrete multipliers (practicing=3x), more lenient
*
* Example with max=7 and base_cost=2 (complement skill):
* - Adaptive (pKnown=0): 2 × 4.0 = 8.0 → filtered (exceeds max)
* - Classic (practicing): 2 × 3.0 = 6.0 → allowed (under max)
*
* This differentiation is key to BKT-driven adaptive problem selection.
*/
export const PURPOSE_COMPLEXITY_BOUNDS: Record<
'focus' | 'reinforce' | 'review' | 'challenge',
Record<SessionPartType, { min: number | null; max: number | null }>
> = {
focus: {
abacus: { min: null, max: 7 }, // Added max to enable adaptive differentiation
visualization: { min: null, max: 5 },
linear: { min: null, max: 7 }, // Added max to enable adaptive differentiation
},
reinforce: {
abacus: { min: null, max: 7 },
visualization: { min: null, max: 5 },
linear: { min: null, max: 7 },
},
review: {
abacus: { min: null, max: 7 },
visualization: { min: null, max: 5 },
linear: { min: null, max: 7 },
},
challenge: {
/** Challenge problems require at least some skill complexity */
abacus: { min: 1, max: null },
visualization: { min: 1, max: null },
linear: { min: 1, max: null },
},
}
/**
* Get complexity bounds for a specific purpose and part type.
*/
export function getComplexityBounds(
purpose: 'focus' | 'reinforce' | 'review' | 'challenge',
partType: SessionPartType
): { min: number | null; max: number | null } {
return PURPOSE_COMPLEXITY_BOUNDS[purpose][partType]
}
export type PurposeComplexityBounds = typeof PURPOSE_COMPLEXITY_BOUNDS
|