/** * Pure scalar reduction formulas — the single source of truth for the * arithmetic behind every list→scalar reducer in the codebase. * * Three reducers used to re-implement these formulas independently and had * silently drifted: * * - `reduceValues` (`dice-stats.ts`) — analytical reduction of materialised * pools; returns `0` on an empty pool. * - `Roller.reduceResults` (`roller.ts`) — runtime reduction of rolled * values; throws on an empty pool. * - `applyAggregatorConcretely` (`program-stats.ts`) — comprehension * aggregation over `Value[]`; throws on an empty pool and adds record / * `count` / `first` / `last` semantics on top of the numeric core. * * The pieces that legitimately differ between those callers — the empty-pool * policy (return `0` vs. throw), the threshold matcher used for `count` * reducers, and the structured-record handling for `sum` — stay at the call * site. The numeric formulas live here so they cannot diverge again. * * Every formula keyed on a non-empty pool ({@link minOf}, {@link maxOf}, * {@link averageOf}, {@link medianOf}) has a non-empty precondition: the caller * applies its own empty-pool policy first. */ /** Sum of `xs` (empty → 0). */ export declare function sumOf(xs: number[]): number; /** Product of `xs` (empty → 1). */ export declare function productOf(xs: number[]): number; /** * Minimum of a non-empty `xs`. * * Uses an explicit loop rather than `Math.min(...xs)`: a dice pool can hold up * to `MAX_DICE_COUNT` entries, and spreading that many arguments risks a * call-stack overflow on some engines. */ export declare function minOf(xs: number[]): number; /** Maximum of a non-empty `xs`. See {@link minOf} for the loop rationale. */ export declare function maxOf(xs: number[]): number; /** Arithmetic mean of a non-empty `xs` (float; no rounding/truncation). */ export declare function averageOf(xs: number[]): number; /** * Median of a non-empty `xs`. * * For an even-length pool the two central values are averaged. Set * `round: true` to round that average to the nearest integer. * * NOTE: the runtime roller (`Roller.reduceResults`) reduces with `round` * unset, while the analytical engine (`reduceValues`) reduces with * `round: true`. That pre-existing tie-break difference is now expressed in a * single place rather than two divergent re-implementations; converging it is * a deliberate semantic decision left to the maintainer. */ export declare function medianOf(xs: number[], opts?: { round?: boolean; }): number;