SPB Git

spb/llmindex Public

The discriminative, contamination-resistant, fully transparent LLM ranking — updated live.

TypeScript 77.9% TeX 15.2% Python 3.7% SQL 1.4% JavaScript 1.1% Shell 0.5%
7.1 KB · 188 lines typescript
Raw Blame History
1/**2 * llmindex.io — math item templates (compositional chains, distractors, counterfactual bases)3 * Author:  Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * License: Proprietary — © Simon-Pierre Boucher, all rights reserved6 *7 * Hardened for frontier discrimination: multi-step composition (errors8 * compound multiplicatively), provably-inert distractor clauses, value9 * re-randomization every run, and counterfactual-rule variants (base-k10 * arithmetic) that separate reasoning from retrieval.11 */12import { ANSWER_FORMAT_INSTRUCTIONS } from '../answer';13import type { Rng } from '../rng';14import type { ItemTemplate } from '../types';1516const LEADS = [17  'Compute the value of the following expression.',18  'Evaluate the expression below and give the result.',19  'Work out the exact value of this expression.',20  'Calculate the following. Show your reasoning, then answer.',21];2223export const mathArithChain: ItemTemplate = {24  id: 'math.arith.chain-v2',25  domain: 'math',26  description:27    'Deep integer arithmetic chain (6-8 dependent operations, 2-4 digit operands) — errors compound multiplicatively.',28  paramSpace: 999 ** 6 * 4 ** 6,29  render(rng: Rng, perturbSeed: string) {30    // Build a dependent chain: v0 = a·b − c; v1 = v0·d + e; v2 = v1 − f·g; …31    const a = rng.int(23, 97);32    const b = rng.int(23, 97);33    const c = rng.int(101, 999);34    const d = rng.int(3, 9);35    const e = rng.int(1001, 9999);36    const f = rng.int(11, 99);37    const g = rng.int(11, 99);38    const h = rng.int(2, 7);39    const v0 = a * b - c;40    const v1 = v0 * d + e;41    const v2 = v1 - f * g;42    const value = v2 * h;43    const expr = `(((${a} × ${b} − ${c}) × ${d} + ${e}) − ${f} × ${g}) × ${h}`;44    return {45      templateId: this.id,46      domain: this.domain,47      prompt: `${rng.pick(LEADS)}\n\n${expr}\n\n${ANSWER_FORMAT_INSTRUCTIONS}`,48      answerKey: String(value),49      grading: 'numeric',50      perturbSeed,51    };52  },53};5455export const mathLinearSolve: ItemTemplate = {56  id: 'math.algebra.system-v2',57  domain: 'math',58  description: 'Two-variable integer linear system solved for a derived quantity (not x or y directly).',59  paramSpace: 20 ** 4 * 200 ** 2,60  render(rng: Rng, perturbSeed: string) {61    const x = rng.int(-40, 40);62    const y = rng.int(-40, 40);63    const a1 = rng.int(2, 9);64    const b1 = rng.int(2, 9);65    const a2 = rng.int(2, 9);66    let b2 = rng.int(2, 9);67    if (a1 * b2 === a2 * b1) b2 += 1; // keep the system non-degenerate68    const c1 = a1 * x + b1 * y;69    const c2 = a2 * x - b2 * y;70    const p = rng.int(2, 6);71    const q = rng.int(2, 6);72    const derived = p * x - q * y;73    return {74      templateId: this.id,75      domain: this.domain,76      prompt:77        `Solve the system, then answer the derived question.\n\n` +78        `${a1}x + ${b1}y = ${c1}\n${a2}x − ${b2}y = ${c2}\n\n` +79        `What is the value of ${p}x − ${q}y?\n\n${ANSWER_FORMAT_INSTRUCTIONS}`,80      answerKey: String(derived),81      grading: 'numeric',82      perturbSeed,83    };84  },85};8687const DISTRACTOR_FACTS = [88  'The warehouse was painted {N} years ago.',89  'A rival firm shipped {N} unrelated parcels the same week.',90  'The delivery van has a {N}-liter fuel tank.',91  'The company was founded {N} kilometers from the port.',92  'Each pallet weighs about {N} grams more when wet.',93];9495export const mathPercentChain: ItemTemplate = {96  id: 'math.percent.chain-v2',97  domain: 'math',98  description:99    'Three successive percentage changes on a base quantity with provably-inert distractor clauses injected.',100  paramSpace: 99 * 40 ** 3 * 5 ** 2 * 200,101  render(rng: Rng, perturbSeed: string) {102    // base multiple of 1000 ⇒ result exact at 3 decimals for the chosen rates103    const base = rng.int(2, 99) * 1000;104    const up1 = rng.int(5, 45);105    const down = rng.int(5, 45);106    const up2 = rng.int(5, 45);107    const value = (((base * (100 + up1)) / 100) * (100 - down)) / 100;108    const final = (value * (100 + up2)) / 100;109    const rounded = Math.round(final * 100) / 100;110    // Inert distractors: quantities that never enter the computation.111    const d1 = rng.pick(DISTRACTOR_FACTS).replace('{N}', String(rng.int(3, 180)));112    const d2 = rng.pick(DISTRACTOR_FACTS).replace('{N}', String(rng.int(3, 180)));113    return {114      templateId: this.id,115      domain: this.domain,116      prompt:117        `An inventory starts at ${base} units. ${d1} In the first month the inventory grows by ${up1}%. ` +118        `${d2} The next month it shrinks by ${down}%, and the month after it grows by ${up2}%. ` +119        `How many units remain (exact value, round to 2 decimals only if needed)?\n\n${ANSWER_FORMAT_INSTRUCTIONS}`,120      answerKey: String(rounded),121      grading: 'numeric',122      perturbSeed,123    };124  },125};126127/** Digits of n in base b (b ≤ 13, digits as letters beyond 9 avoided: b ≤ 13 uses 0-9+A-C but we cap at 13 and exclude ambiguity by using b ≤ 13 with A,B,C). */128function toBase(n: number, b: number): string {129  return n.toString(b).toUpperCase();130}131132export const mathCounterfactualBase: ItemTemplate = {133  id: 'math.counterfactual.base-v1',134  domain: 'math',135  description:136    'Counterfactual-rule arithmetic: add/multiply numbers written in base k (k ∈ {7,8,9,11,13}) — separates rule-following computation from memorized decimal arithmetic.',137  paramSpace: 5 * 2 * 3000 ** 2,138  render(rng: Rng, perturbSeed: string) {139    const b = rng.pick([7, 8, 9, 11, 13] as const);140    const op = rng.pick(['add', 'multiply'] as const);141    const x = op === 'add' ? rng.int(200, 3000) : rng.int(12, 90);142    const y = op === 'add' ? rng.int(200, 3000) : rng.int(12, 90);143    const result = op === 'add' ? x + y : x * y;144    return {145      templateId: this.id,146      domain: this.domain,147      prompt:148        `Work strictly in base ${b}. ${op === 'add' ? 'Add' : 'Multiply'} the base-${b} numbers ` +149        `${toBase(x, b)} and ${toBase(y, b)}. Give the result IN BASE ${b}` +150        `${b > 10 ? ' (digits beyond 9 are A, B, C)' : ''}.\n\n${ANSWER_FORMAT_INSTRUCTIONS}`,151      answerKey: toBase(result, b),152      grading: 'exact',153      perturbSeed,154    };155  },156};157158export const mathChained: ItemTemplate = {159  id: 'math.chained.pipeline-v1',160  domain: 'math',161  description:162    'Three linked sub-problems where each answer feeds the next (R-Horizon-style chaining) — per-step accuracy compounds, amplifying discrimination.',163  paramSpace: 90 ** 4 * 9 ** 3,164  render(rng: Rng, perturbSeed: string) {165    const a = rng.int(12, 89);166    const b = rng.int(12, 89);167    const s1 = a * b; // step 1168    const m = rng.int(3, 9);169    const c = rng.int(100, 999);170    const s2 = s1 * m - c; // step 2171    const dsor = rng.int(3, 9);172    const s3 = Math.floor(s2 / dsor) + (s2 % dsor); // step 3: quotient + remainder173    return {174      templateId: this.id,175      domain: this.domain,176      prompt:177        `Solve the following linked steps; each step uses the previous result.\n\n` +178        `Step 1: P = ${a} × ${b}.\n` +179        `Step 2: Q = P × ${m} − ${c}.\n` +180        `Step 3: divide Q by ${dsor}: let q be the integer quotient and r the remainder. The final answer is q + r.\n\n` +181        `${ANSWER_FORMAT_INSTRUCTIONS}`,182      answerKey: String(s3),183      grading: 'numeric',184      perturbSeed,185    };186  },187};188