congruence-solver
Version:
Single variable linear and quadratic congruence solver
104 lines (95 loc) • 3.74 kB
TypeScript
/**
* Returns the prime factors of the given positive integer in increasing order.
*/
declare function factor(n: number): number[];
/**
* Returns the greatest common divisor of a and b, or 0 if a = b = 0.
*/
declare function gcd(a: number, b: number): number;
/**
* Computes a⁻¹ (mod m) with the extended Euclidean algorithm.
* Returns a number between 0 and m - 1, or NaN if the inverse doesn't exist.
*
* In case strict = false, returns the smallest non-negative solution to the
* a·x = gcd(a, m) (mod m) congruence. The result will be in the
* [0, m / gcd(a, m) - 1] range.
*
* The inverse of each integer is 0 (mod 1), because a * 0 = 0 ≡ 1 (mod 1).
*/
declare function inverseMod(a: number, m: number, strict?: boolean): number;
/**
* Represents a set of residue classes with a common modulus.
* Each residue is an integer in the range [0, mod - 1], inclusive.
* The residue list is sorted in ascending order.
*
* For example, {res: [1, 2], mod: 5} denotes the set of integers n
* such that n ≡ 1 (mod 5) or n ≡ 2 (mod 5).
*/
interface ResidueClasses {
readonly res: readonly number[];
readonly mod: number;
}
/**
* Empty residue class set.
*/
declare const NO_RESIDUES: ResidueClasses;
/**
* Residue classes representing all integers.
*/
declare const ALL_RESIDUES: ResidueClasses;
/**
* Computes the intersection of multiple residue class sets.
*
* The result is a new residue class set that satisfies all the constraints of
* the input residue classes. This corresponds to finding the minimal modulus
* and the associated residues such that:
* For each input rc[i],
* x ≡ any element of rc[i].res (mod rc[i].mod)
*
* If no intersection exists (i.e., the constraints are incompatible),
* the function returns an empty residue class.
*/
declare function intersectResidues(...rc: ResidueClasses[]): ResidueClasses;
/**
* Solves the congruence equation ax + b ≡ 0 (mod m).
*
* If the equation is solvable, returns a residue r and modulus m' such that
* the complete solution set is given by x ≡ r (mod m'). If the equation has no
* solution, returns an empty list for residues and sets m' to 1.
*/
declare function solveLinearCongruence(a: number, b: number, m: number): ResidueClasses;
/**
* Computes (base ** exp) % mod. Returns an integer between 0 and mod - 1.
*
* Preconditions:
* base, exp, mod ∈ ℤ
* base² < 2**53
* 0 ≤ exp < 2**31
* 0 < mod² < 2**53
*/
declare function powMod(base: number, exp: number, mod: number): number;
/**
* Solves the quadratic congruence equation ax² + bx + c ≡ 0 (mod m).
*
* The modulus can be specified either as a number or a list of monotonously
* growing positive prime factors.
*
* Number of results ≤ 2 ** (number of distinct prime factors).
*/
declare function solveQuadraticCongruence(a: number, b: number, c: number, m: number | number[]): ResidueClasses;
/**
* Computes the square root of a modulo p using the Tonelli-Shanks algorithm.
* Solves the congruence x² ≡ a (mod p) and returns the smallest non-negative
* solution, or NaN if no solution exists.
*
* If the equation has solutions, they are symmetric modulo p. Specifically,
* if x is a solution, then -x (or equivalently p-x) is also a solution.
*
* Preconditions:
* - p must be a prime number.
* - p ≤ 94906249 (to ensure that p² ≤ Number.MAX_SAFE_INTEGER, avoiding
* incorrect results or infinite loops caused by floating-point rounding
* errors).
*/
declare function sqrtModPrime(a: number, p: number): number;
export { ALL_RESIDUES, NO_RESIDUES, type ResidueClasses, factor, gcd, intersectResidues, inverseMod, powMod, solveLinearCongruence, solveQuadraticCongruence, sqrtModPrime };