12/20/2025

How the Law School Admissions Calculator Actually Works: A Technical Deep Dive

If you've used our Law School Admissions Calculator, you've seen probability percentages for 191 law schools. But what's actually happening behind the scenes? This post walks through the algorithm in detail—including the actual formulas and code.

The Core Insight: Acceptance Rate Is the Anchor

Most admissions calculators assume that being at a school's median LSAT and GPA gives you a 50% chance of admission. This is wrong.

Think about it: Yale Law School has roughly a 6% acceptance rate. If you're at their median LSAT (174) and median GPA (3.94), you're competitive—but you're also competing against thousands of other applicants with similar or better stats. The idea that median = 50% doesn't match reality at selective schools.

Our model uses a different approach:

probability = acceptance_rate × multiplier(composite_score)

The acceptance rate is the baseline. Your position relative to the school's percentiles determines whether you're multiplied above or below that rate.

Composite Score: Combining LSAT and GPA

To compare an applicant against a school's distribution, we calculate a composite score using Z-score normalization:

// Calculate normalized scores relative to school's distribution
const lsatRange = lsat75 - lsat25;  // Interquartile range
const gpaRange = gpa75 - gpa25;

// Z-scores: how many IQRs away from median
const lsatZ = (lsat - lsat50) / lsatRange;
const gpaZ = (gpa - gpa50) / gpaRange;

// Weighted combination
const composite = (lsatWeight * lsatZ + GPA_WEIGHT * gpaZ) / (totalWeight / 2);

How to interpret composite scores:

Composite ScoreMeaning
0At median for both LSAT and GPA
+1Roughly at 75th percentile overall
+2Far above 75th percentile
-1Roughly at 25th percentile overall
-2Far below 25th percentile

Tier-Based LSAT Weighting

Here's something not obvious: LSAT weight varies by school tier.

function getLsatWeight(rank: number): number {
  if (rank <= 14) return 1.1;   // T14: nearly balanced with GPA
  if (rank <= 50) return 1.4;   // T15-50: slight LSAT advantage
  if (rank <= 100) return 1.6;  // T51-100: LSAT more dominant
  return 1.8;                   // Below T100: LSAT very dominant
}

Why does this happen?

T14 schools receive so many applicants with 170+ LSATs that they can afford to weight GPA almost equally. These schools are also more "holistic" in their review—they have the luxury of being selective beyond just numbers.

As you move down the rankings, schools increasingly rely on LSAT as the primary differentiator. A standardized test is easier to compare across institutions with varying grade inflation. By the time you reach schools outside the T100, LSAT is weighted nearly 1.8x more than GPA.

Splitter and Reverse-Splitter Handling

One of the trickiest parts of any admissions model is handling splitters (high LSAT, low GPA) and reverse splitters (high GPA, low LSAT).

A naive weighted average would treat a 175 LSAT / 3.3 GPA the same as a 160 LSAT / 3.9 GPA if they happened to average out equally. But that's not how admissions works. Being above median on any stat provides some protection.

We implement this through composite floors:

if (category === 'splitter') {
  // LSAT is above median - calculate strength
  const lsatAdvantage = Math.max(0, lsatZ);
  // Floor: composite can't drop below -0.5 + bonus for LSAT strength
  const splitterFloor = -0.5 + lsatAdvantage * 0.5;
  composite = Math.max(composite, splitterFloor);
} 
else if (category === 'reverse-splitter') {
  // GPA is above median - calculate strength
  const gpaAdvantage = Math.max(0, gpaZ);
  // Floor: composite can't drop below -0.6 + bonus for GPA strength
  // Slightly lower floor than splitters (GPA weighted less)
  const reverseSplitterFloor = -0.6 + gpaAdvantage * 0.4;
  composite = Math.max(composite, reverseSplitterFloor);
}

Key detail: Splitters get a floor of -0.5, while reverse splitters get a floor of -0.6. This reflects reality—LSAT is the more important factor, so being strong on LSAT provides slightly more protection.

The LSAT Floor Penalty: Why Reverse Splitters Face Limits

This is one of the most important features of the model.

Law schools have implicit hard cutoffs below certain LSATs where admission becomes nearly impossible regardless of GPA. A 4.0 GPA cannot compensate for a 148 LSAT at a T50 school with a 25th percentile LSAT of 160.

We model this with a progressive penalty:

function getLsatFloorPenalty(lsat: number, lsat25: number, rank: number): number {
  const pointsBelow = lsat25 - lsat;
  
  if (pointsBelow <= 0) return 0;  // No penalty if at or above 25th

  let penalty = 0;

  if (pointsBelow >= 15) {
    // Extreme: 15+ points below 25th
    penalty = 2.0 + (pointsBelow - 15) * 0.1;
  } else if (pointsBelow >= 10) {
    // Severe: 10-14 points below 25th
    penalty = 1.0 + (pointsBelow - 10) * 0.2;
  } else if (pointsBelow >= 5) {
    // Moderate: 5-9 points below 25th
    penalty = 0.3 + (pointsBelow - 5) * 0.14;
  } else {
    // Minor: 1-4 points below 25th
    penalty = pointsBelow * 0.06;
  }

  // T14 schools are stricter
  if (rank <= 14) {
    penalty *= 1.3;
  } else if (rank <= 50) {
    penalty *= 1.15;
  }

  return penalty;
}

Penalty ranges by LSAT deficit:

Points Below 25thPenalty Range
1-4 points0.06 - 0.24
5-9 points0.30 - 0.86
10-14 points1.0 - 1.8
15+ points2.0+

This prevents the calculator from showing unrealistic optimism for reverse splitters with LSATs far below a school's range.

GPA Floor Penalty: T14 Only

Elite schools also show implicit GPA cutoffs:

function getGpaFloorPenalty(gpa: number, rank: number): number {
  if (rank > 14) return 0;  // Only applies to T14

  // T6 (HYS + CCN) have higher floors
  if (rank <= 6) {
    if (gpa < 3.5) return 0.5;   // Heavy penalty
    if (gpa < 3.7) return 0.25;  // Moderate penalty
    return 0;
  }

  // T7-14 slightly more forgiving
  if (gpa < 3.3) return 0.4;
  if (gpa < 3.5) return 0.2;
  return 0;
}

At Harvard, Yale, and Stanford, a GPA below 3.5 is a significant hurdle regardless of LSAT. The T7-14 are slightly more forgiving, but a sub-3.3 GPA still triggers a penalty.

The Below-Both Penalty: Synergistic Disadvantage

When an applicant is below both medians, schools have zero incentive to admit them—they hurt both the LSAT median and the GPA median in the rankings calculation.

We model this with a product-based penalty:

function getBelowBothPenalty(lsatZ: number, gpaZ: number): number {
  if (lsatZ >= 0 || gpaZ >= 0) return 0;  // Only when BOTH below

  const lsatDeficit = Math.abs(lsatZ);
  const gpaDeficit = Math.abs(gpaZ);

  // Synergistic harm: penalty = product of deficits
  const rawPenalty = lsatDeficit * gpaDeficit * 0.4;
  return Math.min(rawPenalty, 0.6);  // Capped at 0.6
}

Being 0.5 IQR below on both stats results in: 0.5 × 0.5 × 0.4 = 0.1 penalty. Being 1.0 IQR below on both stats results in: 1.0 × 1.0 × 0.4 = 0.4 penalty.

The product formula captures the compounding disadvantage of weakness in both areas.

The Multiplier Curve

Once we have the composite score, we convert it to a multiplier that scales the base acceptance rate:

function getPercentileMultiplier(composite: number, acceptanceRate: number): number {
  // Ultra-selective schools: reduce multiplier (holistic factors dominate)
  const selectivityFactor = acceptanceRate < 0.1 ? 0.65 : 1.0;

  // Less selective schools: median applicants have better odds
  const baseMultiplier = 
    acceptanceRate > 0.18 ? 1.7 : 
    acceptanceRate > 0.15 ? 1.4 : 
    acceptanceRate > 0.12 ? 1.2 : 1.0;

  if (composite >= 1) {
    // At/above 75th percentile - strong advantage
    const multiplier = baseMultiplier + 1.3 + (composite - 1) * 1.5;
    return Math.min(5.0, multiplier) * selectivityFactor;
  } else if (composite >= 0) {
    // Between median and 75th - accelerating curve
    return (baseMultiplier + composite * 1.3 + composite * composite * 0.3) * selectivityFactor;
  } else if (composite >= -1) {
    // Between 25th and median
    return Math.max(0.4, baseMultiplier + composite * (baseMultiplier - 0.5));
  } else if (composite >= -2) {
    // Far below 25th
    return Math.max(0.15, 0.5 + (composite + 1) * 0.35);
  } else {
    // Very far below 25th
    return Math.max(0.05, 0.15 + (composite + 2) * 0.05);
  }
}

Key behaviors:

  • At median (composite = 0): multiplier is roughly 1.0-1.7x depending on school selectivity
  • At 75th percentile (composite = +1): multiplier is roughly 2.5-3.5x
  • At 25th percentile (composite = -1): multiplier is roughly 0.4-0.5x
  • Ultra-selective schools (<10% acceptance): all multipliers reduced by 35%

Probability Caps by Tier

Even with a perfect composite score, we cap probabilities based on school selectivity:

if (effectiveAcceptanceRate < 0.08) {
  // Yale, Stanford, Harvard tier
  probability = Math.min(probability, 30 + composite * 5);
} else if (effectiveAcceptanceRate < 0.12) {
  // Chicago, Columbia tier
  probability = Math.min(probability, 45 + composite * 8);
} else if (effectiveAcceptanceRate < 0.25) {
  // T7-20 tier
  probability = Math.min(probability, 65 + composite * 10);
} else if (effectiveAcceptanceRate < 0.4) {
  // T20-40 tier
  const tierCap = effectiveAcceptanceRate < 0.32 ? 65 : 
                  effectiveAcceptanceRate < 0.37 ? 72 : 78;
  probability = Math.min(probability, tierCap + composite * 5);
} else if (effectiveAcceptanceRate < 0.5) {
  // T40-50 tier
  probability = Math.min(probability, 82 + composite * 5);
} else {
  // T50+ 
  probability = Math.min(probability, 92 + composite * 3);
}

Why these caps?

At Yale (~6% acceptance), even a +2 composite score (far above 75th percentile on everything) maxes out around 35-40%. This reflects reality: perfect numbers don't guarantee admission at ultra-selective schools. Holistic factors—work experience, personal statement, recommendations, diversity—matter more when everyone has near-perfect stats.

Confidence Intervals

We also output a confidence range that reflects uncertainty:

const uncertainty = 3 + Math.abs(composite) * 2;
const rangeMin = Math.max(0.1, probability - uncertainty);
const rangeMax = Math.min(99, probability + uncertainty);
  • Near median: ±5% range (more predictable)
  • At extremes: ±7-10% range (less predictable)

Extreme composite scores are inherently less certain because there's less data on applicants at the tails of the distribution.

Data Source: ABA 509 Reports

The percentiles (25th/50th/75th for LSAT and GPA) come from ABA Standard 509 Information Reports, which law schools are required to publish annually. These show the actual distribution of enrolled students, not just admitted students.

One important note: the GPA in these reports is the LSAC-calculated UGPA, not your transcript GPA. LSAC recalculates using its own methodology, which can differ from what your school reports.

Putting It All Together

Here's the full flow:

  1. Normalize LSAT and GPA into Z-scores using each school's IQR
  2. Weight LSAT based on school tier (1.1x for T14, up to 1.8x for T100+)
  3. Calculate initial composite score
  4. Apply floors for splitters and reverse-splitters
  5. Apply penalties for LSAT floor violations, GPA floor violations (T14), and below-both scenarios
  6. Convert composite to multiplier based on selectivity
  7. Calculate probability as acceptance_rate × multiplier
  8. Cap based on tier-specific maximums
  9. Bound between 0.1% and 95%

The result is a prediction that respects the fundamental reality: acceptance rate is the anchor, and your percentile position determines how much above or below that baseline you fall.

Takeaway

This model is designed to reflect how law school admissions actually works—not how we might naively assume it works. The key insights:

  1. Acceptance rate, not median stats, is the baseline
  2. LSAT matters more at lower-ranked schools
  3. Splitters have more protection than reverse splitters
  4. There are hard LSAT floors that GPA can't overcome
  5. Perfect stats don't guarantee admission at elite schools

Understanding these dynamics can help you build a smarter school list and set realistic expectations.

Try the Admissions Calculator

HFL LSAT Advisor

Online

Hi! I'm HFL's LSAT advisor.

Tell me your score and goal and I'll point you to the right plan — or ask me anything.