Supply-Side Agent Modeling: Students & High Schools

Source: supply-side.md


Supply-Side Agent Modeling: Students & High Schools

Research for the college admissions Agent-Based Model (ABM). Covers statistical distributions, feeder school effects, application strategy, student archetypes, and high school type distributions.


1. Correlated GPA/SAT Distributions

Real-World National Statistics

Metric Value Source
National mean unweighted GPA 3.0 NAEP / NCES
GPA standard deviation ~0.6-0.7 NCES 2011, commonly used in research
Female avg GPA 3.10 NAEP
Male avg GPA 2.90 NAEP
National mean SAT (2024) 1024 College Board 2024 Annual Report
SAT standard deviation 229 College Board
SAT ERW mean 519 College Board
SAT Math mean 505 College Board
SAT test-takers (2024) ~1.97 million College Board

GPA by demographic group:

GPA in core subjects only: 2.79 (overall 3.0 boosted by non-core electives).

GPA-SAT Correlation

The correlation between high school GPA and SAT scores is approximately r = 0.5 to 0.65 depending on the population studied:

For simulation, use r = 0.6 as the GPA-SAT correlation coefficient.

Competitiveness Thresholds

Tier GPA Range SAT Range Approx. Percentile
Elite / T20-competitive 3.8-4.0 1450-1600 Top 5%
Highly competitive 3.5-3.8 1300-1450 Top 15%
Competitive 3.2-3.5 1150-1300 Top 35%
Average 2.8-3.2 950-1150 35th-65th
Below average < 2.8 < 950 Below 35th

Algorithm: Generating Correlated GPA/SAT with Box-Muller + Cholesky

To generate correlated bivariate normal samples (GPA, SAT) in JavaScript:

Step 1: Box-Muller Transform (generate two independent standard normal variates)

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6Mjg2LCJhdHRycyI6eyJieSI6ImFpOmNsYXVkZSJ9fV0= function boxMuller() { let u1, u2; do { u1 = Math.random(); } while (u1 === 0); // avoid log(0) u2 = Math.random(); const z0 = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2); const z1 = Math.sqrt(-2 * Math.log(u1)) * Math.sin(2 * Math.PI * u2); return [z0, z1]; }

**Step 2: Cholesky Decomposition for 2x2** (apply correlation)

For a 2x2 correlation matrix with correlation `rho`:

L = [[1, 0], [rho, sqrt(1 - rho^2)]]

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6MTk0LCJhdHRycyI6eyJieSI6ImFpOmNsYXVkZSJ9fV0=
function generateCorrelatedPair(rho) {
  const [z0, z1] = boxMuller();
  const x = z0;
  const y = rho * z0 + Math.sqrt(1 - rho * rho) * z1;
  return [x, y]; // two correlated standard normals
}

Step 3: Scale to GPA and SAT distributions

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6NTEzLCJhdHRycyI6eyJieSI6ImFpOmNsYXVkZSJ9fV0= function generateStudentStats(config) { const { gpaMean = 3.0, gpaSD = 0.65, satMean = 1050, satSD = 220, rho = 0.6 // GPA-SAT correlation } = config;

const [zGPA, zSAT] = generateCorrelatedPair(rho);

let gpa = gpaMean + gpaSD * zGPA; let sat = satMean + satSD * zSAT;

// Clamp to valid ranges gpa = Math.max(0.0, Math.min(4.0, gpa)); sat = Math.max(400, Math.min(1600, Math.round(sat / 10) * 10)); // round to nearest 10

return { gpa: Math.round(gpa * 100) / 100, sat }; }

**Step 4: Vary parameters by school type** (see Section 5)

Each high school type can have different `gpaMean`, `gpaSD`, `satMean`, `satSD`, and `rho` to reflect different student populations.

### Grade Inflation Adjustment

GPA inflation has been significant: in 2016, 47% of seniors graduated with an A average, up from 38% in 1998. AP/IB enrollment at affluent schools has expanded much faster, inflating weighted GPAs.

**Simulation approach:** Assign each school a `gpaInflation` factor (0.0 to 0.4) that gets added to raw GPA, then clamp at 4.0. Elite private schools may have grade deflation (negative adjustment) while some public schools have inflation.

***

## 2. Feeder School Multipliers

### What Are Feeder Schools?

Feeder schools are high schools that send a disproportionate number of graduates to elite universities. The Harvard Crimson (2024) found that **1 in 11 students** accepted to Harvard comes from just **21 high schools**. Of the top 100 feeder schools to Ivy League, **94 are private**.

### Key Feeder Schools and Their Rates

| School                   | Type             | Ivy+ Acceptance Rate                         | Notes                         |
| ------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Phillips Exeter Academy  | Private boarding | ~19% to HYPSM                                | ~40% to top-25 schools        |
| Phillips Academy Andover | Private boarding | ~11 students/year to Harvard from ~350 grads | ~3% of class to Harvard alone |
| Trinity School (NYC)     | Private day      | ~40% to Ivy League                           | Top NYC feeder                |
| The Dalton School (NYC)  | Private day      | ~31% to Ivy League                           | Strong Cornell/Brown/Columbia |
| Stuyvesant High School   | Public exam      | 40.9% Ivy League (Class of 2021)             | Top public feeder             |
| Boston Latin School      | Public exam      | 100+ students to Harvard 2009-2024           | Top public feeder             |

**Key insight:** 12 of the 21 top Harvard feeders are private, with tuition in the $50K-60K range. However, many feeder school admits are recruited athletes, so the "typical student" advantage may be less than aggregate numbers suggest.

### Why Feeder Schools Have an Advantage

1. **Dedicated college counselors** with 30-40 student caseloads (vs. 400+ at public schools)
2. **Institutional relationships** with admissions offices
3. **Course rigor** recognized by admissions (AP/IB/honors curriculum well-known to AOs)
4. **Legacy/donor concentration** (wealthy alumni families)
5. **Recruited athletes** (especially in sports like rowing, lacrosse, fencing)

### How Colleges Assess School Rigor

* Admissions officers receive a **School Profile** with each transcript showing curriculum difficulty, grading scale, and course offerings.

* AP exam scores serve as a **standardized benchmark** that normalizes across schools.

* Schools are assessed in context: a 3.5 at a known grade-deflating school is valued differently from a 3.9 at a known inflating school.

### Simulation Parameters for Feeder School Multiplier

**Recommended multiplier ranges applied to admission probability:**

| School Category                                | Multiplier      | Rationale                                                                 |
| ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Top 21 feeder (Exeter, Andover, Trinity, etc.) | 1.8-2.5x        | 3-10x raw acceptance rate, but partially explained by stronger applicants |
| Elite private (top 100 feeder)                 | 1.4-1.8x        | Strong counseling, institutional relationships                            |
| Competitive public/exam (Stuyvesant, TJ)       | 1.3-1.6x        | Recognized rigor, but less counseling advantage                           |
| Strong suburban public                         | 1.0-1.2x        | Some schools known to AOs                                                 |
| Average public                                 | 1.0x (baseline) | No particular advantage or disadvantage                                   |
| Under-resourced public                         | 0.8-1.0x        | Limited counseling, but first-gen can offset                              |

**Implementation approach:** Apply as a hidden multiplier to the student's admission score:

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6OTksImF0dHJzIjp7ImJ5IjoiYWk6Y2xhdWRlIn19XQ==
function applySchoolMultiplier(baseScore, school) {
  return baseScore * school.feederMultiplier;
}

The multiplier captures the combined effect of counseling quality, institutional reputation, and AO familiarity, NOT the effect of better student stats (which should already be reflected in higher GPA/SAT).


3. Application Portfolio Strategy

National Application Statistics (2024-2025)

Metric Value Source
Average applications per student (Common App) 6.80 Common App End-of-Season Report 2024-25
Total Common App applicants ~1.5 million Common App
Total applications submitted ~10.2 million Common App
YoY increase in apps per student +2% Common App
YoY increase in applicant count +5% Common App
Common App school limit 20 schools Common App policy

Application Counts by Student Tier

The national average of 6.8 masks huge variance by student ambition level:

Student Type Typical App Count Safety Target Reach
Low-ambition / local 2-4 1-2 1-2 0
Average college-bound 5-8 1-2 2-4 1-2
High-achiever (T20 aspirant) 10-15 1-2 3-4 6-9
Shotgunner 16-20 1-2 2-3 12-15

The "shotgun" approach (applying to 16-20+ schools, mostly reaches) has become increasingly common among T20 aspirants. The Common App limit of 20 schools is the hard cap.

The Portfolio Rule

The commonly cited "2-3-5" rule (2 safeties, 3 targets, 5 reaches) is a simplified heuristic. More accurate guidelines from College Board and counselors:

How Students Classify Safety/Target/Reach

Based on the student's own GPA and SAT relative to the school's admitted student profile:

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6NTEyLCJhdHRycyI6eyJieSI6ImFpOmNsYXVkZSJ9fV0= function classifySchool(student, college) { // Compare student stats to college's middle 50% range const satMid = (college.sat25 + college.sat75) / 2; const gpaMid = (college.gpa25 + college.gpa75) / 2;

const satDelta = (student.sat - satMid) / (college.sat75 - college.sat25); const gpaDelta = (student.gpa - gpaMid) / (college.gpa75 - college.gpa25); const composite = (satDelta + gpaDelta) / 2;

if (composite > 0.5) return 'safety'; if (composite > -0.3) return 'target'; return 'reach'; }

### Application Strategy Algorithm for Simulation

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6MTAzNSwiYXR0cnMiOnsiYnkiOiJhaTpjbGF1ZGUifX1d
function buildApplicationList(student, colleges, config) {
  const classified = colleges.map(c => ({
    college: c,
    type: classifySchool(student, c),
    desirability: c.prestige * student.ambition + Math.random() * 0.2
  }));

  // Sort each category by desirability
  const safeties = classified.filter(c => c.type === 'safety')
    .sort((a, b) => b.desirability - a.desirability);
  const targets = classified.filter(c => c.type === 'target')
    .sort((a, b) => b.desirability - a.desirability);
  const reaches = classified.filter(c => c.type === 'reach')
    .sort((a, b) => b.desirability - a.desirability);

  // Pick based on student ambition
  const totalApps = student.appCount; // determined by archetype
  const numSafety = Math.max(1, Math.round(totalApps * 0.15));
  const numTarget = Math.round(totalApps * 0.35);
  const numReach = totalApps - numSafety - numTarget;

  return [
    ...safeties.slice(0, numSafety),
    ...targets.slice(0, numTarget),
    ...reaches.slice(0, numReach)
  ].map(c => c.college);
}

4. Student Archetypes

ALDC Composition at Elite Schools (Harvard Data)

ALDC = Athletes, Legacies, Dean's Interest List (donors), Children of faculty/staff.

Category % of Applicant Pool Admission Rate % of Admitted Class
Recruited athletes ~1-2% 86% 10-15%
Legacy applicants ~3-5% 33% ~14%
Dean's interest list (donors) ~1-2% 42% ~10%
Children of faculty/staff ~1% 47% ~2-3%
Total ALDC ~5% varies ~30%
Non-ALDC applicants ~95% ~6% ~70%

Key stat: Among white admits to Harvard, over 43% are ALDC. Among non-white admits, ALDC share is less than 16%.

SAT-Equivalent Advantage of Hooks

Research (Espenshade & Radford, 2009; Arcidiacono et al., 2019) estimated admission advantages equivalent to SAT point bonuses:

Hook SAT-Equivalent Bonus Source
Recruited athlete ~200 points Espenshade
Legacy ~160 points Espenshade
Underrepresented minority ~185-230 points Espenshade
First-generation ~100 points (estimated) Various analyses
Donor/development case ~160-200 points Harvard trial data

Archetype Definitions for Simulation

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6MjgxNSwiYXR0cnMiOnsiYnkiOiJhaTpjbGF1ZGUifX1d const STUDENT_ARCHETYPES = { publicSchoolOverachiever: { label: "Public School Overachiever", frequency: 0.35, // 35% of T20 applicant pool gpaBoost: 0, // no artificial boost satBoost: 0, ecStrength: 0.6, // moderate ECs essayStrength: 0.6, hookMultiplier: 1.0, // no hook appCount: { min: 8, max: 15 }, ambition: 0.7 }, stemProdigy: { label: "STEM Prodigy", frequency: 0.10, gpaBoost: 0.1, // tends toward higher GPA satBoost: 80, // strong test-taker ecStrength: 0.8, // research, olympiads essayStrength: 0.5, hookMultiplier: 1.15, // slight STEM advantage at tech schools appCount: { min: 8, max: 14 }, ambition: 0.85 }, recruitedAthlete: { label: "Recruited Athlete", frequency: 0.08, gpaBoost: -0.1, // slightly lower academics satBoost: -30, ecStrength: 0.3, // athletics is the EC essayStrength: 0.5, hookMultiplier: 3.5, // massive admission boost appCount: { min: 3, max: 6 }, // targeted via coaches ambition: 0.9 }, legacyApplicant: { label: "Legacy Applicant", frequency: 0.06, gpaBoost: 0.05, satBoost: 20, ecStrength: 0.6, essayStrength: 0.6, hookMultiplier: 2.5, appCount: { min: 6, max: 12 }, ambition: 0.8 }, donorChild: { label: "Donor / Development Case", frequency: 0.02, gpaBoost: 0, satBoost: 0, ecStrength: 0.5, essayStrength: 0.5, hookMultiplier: 4.0, // very strong institutional interest appCount: { min: 4, max: 8 }, ambition: 0.85 }, firstGeneration: { label: "First-Generation Student", frequency: 0.15, gpaBoost: -0.05, // slightly lower due to resource constraints satBoost: -40, ecStrength: 0.5, essayStrength: 0.7, // compelling narrative hookMultiplier: 1.4, appCount: { min: 5, max: 10 }, ambition: 0.6 }, artsTalent: { label: "Arts / Humanities Talent", frequency: 0.08, gpaBoost: 0.05, satBoost: -10, ecStrength: 0.85, // portfolio/performances essayStrength: 0.8, // strong writer hookMultiplier: 1.2, appCount: { min: 8, max: 14 }, ambition: 0.75 }, internationalElite: { label: "International Elite", frequency: 0.08, gpaBoost: 0.1, satBoost: 60, ecStrength: 0.7, essayStrength: 0.6, hookMultiplier: 1.1, // slight diversity bonus but no need-blind appCount: { min: 8, max: 15 }, ambition: 0.9 }, averageApplicant: { label: "Average College-Bound Student", frequency: 0.08, gpaBoost: -0.2, satBoost: -60, ecStrength: 0.4, essayStrength: 0.4, hookMultiplier: 1.0, appCount: { min: 4, max: 8 }, ambition: 0.4 } };

**Note on frequency:** These frequencies represent the composition of the T20-aspirant applicant pool, not the general student population. In the general population, "average applicant" would be ~60%+ and T20-specific archetypes much smaller.

### Income Distribution Context (Chetty/Opportunity Insights)

* 67% of Harvard undergrads come from the **top 20%** of the income distribution

* Only 4.5% come from the **bottom 20%**

* Children with parents in the top 1% are **77x more likely** to attend an Ivy-Plus college than children from the bottom 20%

* Among Harvard recruited athletes (Class of 2025): **83% white**, 46.3% from families earning $250K+

***

## 5. High School Type Distributions

### National School Breakdown

| School Type         | Count (HS) | % of Schools | % of Students |
| -------------------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Traditional public  | ~20,000    | ~75%         | ~85%          |
| Public charter      | ~2,500     | ~9%          | ~6.6%         |
| Public magnet/exam  | ~1,400     | ~5%          | ~4.9%         |
| Private (all types) | ~2,845     | ~11%         | ~10%          |

Source: NCES, Pew Research Center (2024), MDR Education

**Private school sub-types:**

* Religious (Catholic, etc.): ~60% of private schools

* Independent/prep: ~25%

* Elite boarding (NAIS top-tier): ~50-100 schools nationally

### School Type Effects on GPA and Rigor

| School Type               | Avg Unweighted GPA | GPA Inflation                | AP/IB Courses | Course Rigor  |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Elite private/boarding    | 3.2-3.5            | Low (grade deflation common) | 15-25 APs     | Very high     |
| Competitive public/magnet | 3.1-3.4            | Moderate                     | 15-30 APs     | High          |
| Strong suburban public    | 3.0-3.3            | Moderate-High                | 10-20 APs     | Moderate-High |
| Average public            | 2.8-3.1            | Moderate                     | 5-15 APs      | Moderate      |
| Under-resourced public    | 2.5-2.9            | Variable                     | 2-8 APs       | Low-Moderate  |
| Private religious         | 3.0-3.3            | Moderate                     | 5-15 APs      | Moderate      |

**Key insight on GPA inflation:** AP/IB enrollment at affluent schools has expanded much faster, creating wider GPA inflation at those schools. A student from a rigorous private school may have 3.57 unweighted while peers at other schools show 3.8-4.4 for equivalent ability.

### T20 Admit Source Distribution

Approximate breakdown of where T20 admits come from:

| School Type                               | % of T20 Admits | Over/Under-representation |
| ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Elite private/boarding (top ~200 schools) | ~25-30%         | ~3x over-represented      |
| Competitive public/magnet                 | ~10-15%         | ~2x over-represented      |
| Strong suburban public                    | ~30-35%         | ~1x (proportional)        |
| Average/under-resourced public            | ~15-20%         | Under-represented         |
| International                             | ~10-15%         | N/A                       |

**The "1 in 11" stat:** 21 high schools account for ~9% of Harvard admits. These 21 schools represent less than 0.1% of all US high schools.

Most Ivy League schools admit roughly **25% from private schools** and **60-70% from public schools**, but this merely reflects application volume -- private school students are proportionally much more likely to apply to and attend elite schools.

### High School Type Configuration for Simulation

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6MzQ0MiwiYXR0cnMiOnsiYnkiOiJhaTpjbGF1ZGUifX1d
const HIGH_SCHOOL_TYPES = {
  elitePrivate: {
    label: "Elite Private / Boarding",
    frequency: 0.02,        // 2% of all schools
    studentCount: { min: 80, max: 200 },
    gpaMean: 3.4, gpaSD: 0.45,
    satMean: 1350, satSD: 150,
    gpaInflation: -0.1,     // grade deflation
    feederMultiplier: 2.0,
    courseRigor: 0.95,
    archetypeWeights: {
      legacyApplicant: 0.15,
      donorChild: 0.05,
      recruitedAthlete: 0.12,
      stemProdigy: 0.10,
      artsTalent: 0.08,
      internationalElite: 0.15,
      publicSchoolOverachiever: 0.30,  // relabeled as "overachiever" here
      firstGeneration: 0.02,
      averageApplicant: 0.03
    }
  },
  competitivePublic: {
    label: "Competitive Public / Magnet / Exam",
    frequency: 0.05,
    studentCount: { min: 200, max: 800 },
    gpaMean: 3.3, gpaSD: 0.50,
    satMean: 1280, satSD: 170,
    gpaInflation: 0.0,
    feederMultiplier: 1.5,
    courseRigor: 0.85,
    archetypeWeights: {
      legacyApplicant: 0.03,
      donorChild: 0.01,
      recruitedAthlete: 0.05,
      stemProdigy: 0.15,
      artsTalent: 0.08,
      internationalElite: 0.05,
      publicSchoolOverachiever: 0.45,
      firstGeneration: 0.10,
      averageApplicant: 0.08
    }
  },
  strongSuburban: {
    label: "Strong Suburban Public",
    frequency: 0.15,
    studentCount: { min: 300, max: 600 },
    gpaMean: 3.1, gpaSD: 0.55,
    satMean: 1150, satSD: 190,
    gpaInflation: 0.15,
    feederMultiplier: 1.1,
    courseRigor: 0.70,
    archetypeWeights: {
      legacyApplicant: 0.04,
      donorChild: 0.01,
      recruitedAthlete: 0.08,
      stemProdigy: 0.06,
      artsTalent: 0.06,
      internationalElite: 0.02,
      publicSchoolOverachiever: 0.40,
      firstGeneration: 0.12,
      averageApplicant: 0.21
    }
  },
  averagePublic: {
    label: "Average Public",
    frequency: 0.55,
    studentCount: { min: 200, max: 500 },
    gpaMean: 2.9, gpaSD: 0.65,
    satMean: 1020, satSD: 210,
    gpaInflation: 0.1,
    feederMultiplier: 1.0,
    courseRigor: 0.50,
    archetypeWeights: {
      legacyApplicant: 0.02,
      donorChild: 0.005,
      recruitedAthlete: 0.06,
      stemProdigy: 0.03,
      artsTalent: 0.04,
      internationalElite: 0.01,
      publicSchoolOverachiever: 0.25,
      firstGeneration: 0.20,
      averageApplicant: 0.385
    }
  },
  underResourced: {
    label: "Under-Resourced Public",
    frequency: 0.20,
    studentCount: { min: 100, max: 400 },
    gpaMean: 2.6, gpaSD: 0.70,
    satMean: 900, satSD: 200,
    gpaInflation: 0.05,
    feederMultiplier: 0.9,
    courseRigor: 0.30,
    archetypeWeights: {
      legacyApplicant: 0.01,
      donorChild: 0.005,
      recruitedAthlete: 0.04,
      stemProdigy: 0.02,
      artsTalent: 0.03,
      internationalElite: 0.005,
      publicSchoolOverachiever: 0.15,
      firstGeneration: 0.35,
      averageApplicant: 0.39
    }
  },
  privateReligious: {
    label: "Private Religious (Catholic, etc.)",
    frequency: 0.03,
    studentCount: { min: 100, max: 300 },
    gpaMean: 3.1, gpaSD: 0.55,
    satMean: 1100, satSD: 190,
    gpaInflation: 0.1,
    feederMultiplier: 1.1,
    courseRigor: 0.60,
    archetypeWeights: {
      legacyApplicant: 0.05,
      donorChild: 0.02,
      recruitedAthlete: 0.08,
      stemProdigy: 0.05,
      artsTalent: 0.05,
      internationalElite: 0.03,
      publicSchoolOverachiever: 0.35,
      firstGeneration: 0.08,
      averageApplicant: 0.29
    }
  }
};

6. Complete Student Generation Pipeline

Putting it all together, the simulation should generate students in this order:

Step 1: Generate High Schools

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6NDM5LCJhdHRycyI6eyJieSI6ImFpOmNsYXVkZSJ9fV0= function generateHighSchools(count) { const schools = []; for (let i = 0; i < count; i++) { // Weight by frequency const type = weightedRandomPick(HIGH_SCHOOL_TYPES); const config = HIGH_SCHOOL_TYPES[type]; schools.push({ id: i, type: type, name: generateSchoolName(type), ...config, studentCount: randomInt(config.studentCount.min, config.studentCount.max) }); } return schools; }

### Step 2: Generate Students per School

```javascript proof:W3sidHlwZSI6InByb29mQXV0aG9yZWQiLCJmcm9tIjowLCJ0byI6MTUwMywiYXR0cnMiOnsiYnkiOiJhaTpjbGF1ZGUifX1d
function generateStudentsForSchool(school) {
  const students = [];
  for (let i = 0; i < school.studentCount; i++) {
    // Pick archetype based on school's weights
    const archetype = weightedRandomPick(school.archetypeWeights);
    const archetypeConfig = STUDENT_ARCHETYPES[archetype];

    // Generate correlated GPA/SAT using school params + archetype boosts
    const adjustedGPAMean = school.gpaMean + archetypeConfig.gpaBoost + school.gpaInflation;
    const adjustedSATMean = school.satMean + archetypeConfig.satBoost;

    const { gpa, sat } = generateStudentStats({
      gpaMean: adjustedGPAMean,
      gpaSD: school.gpaSD,
      satMean: adjustedSATMean,
      satSD: school.satSD,
      rho: 0.6
    });

    // EC and essay strength with randomness
    const ecStrength = archetypeConfig.ecStrength + (Math.random() - 0.5) * 0.3;
    const essayStrength = archetypeConfig.essayStrength + (Math.random() - 0.5) * 0.3;

    // Application count
    const appCount = randomInt(
      archetypeConfig.appCount.min,
      archetypeConfig.appCount.max
    );

    students.push({
      id: `${school.id}-${i}`,
      schoolId: school.id,
      archetype,
      gpa,
      sat,
      ecStrength: clamp(ecStrength, 0, 1),
      essayStrength: clamp(essayStrength, 0, 1),
      hookMultiplier: archetypeConfig.hookMultiplier,
      appCount,
      ambition: archetypeConfig.ambition + (Math.random() - 0.5) * 0.2,
      feederMultiplier: school.feederMultiplier
    });
  }
  return students;
}

Step 3: Build Application Lists

Each student builds a portfolio of safety/target/reach schools based on their stats, archetype, and ambition level (see Section 3 algorithm).

Step 4: Submit to Admission Rounds

Students submit applications through the ED -> EA/REA -> EDII -> RD pipeline based on their strategy (determined by archetype and ambition).


Sources