@lucadani7/algonodejs-for-beginners
Version:
Just a simple Node.js package with some basic algorithms perfect for people just starting out. It's got easy-to-understand TypeScript versions of stuff like sorting, searching, math with numbers, and messing with strings.
67 lines (66 loc) • 2.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EuclidClass = void 0;
const AtomicIntegerNode_1 = require("./AtomicIntegerNode");
class EuclidClass {
static gcd(a, b) {
return b === 0n ? a : this.gcd(b, a % b);
}
static lcm(a, b) {
return (a * b) / this.gcd(a, b);
}
static gcdExtended(a, b) {
if (b === 0n) {
return [a, new AtomicIntegerNode_1.AtomicIntegerNode(1n), new AtomicIntegerNode_1.AtomicIntegerNode(0n)];
}
const [dPrev, xPrev, yPrev] = this.gcdExtended(b, a % b);
const x = new AtomicIntegerNode_1.AtomicIntegerNode(yPrev.get());
const y = new AtomicIntegerNode_1.AtomicIntegerNode(xPrev.get() - (a / b) * yPrev.get());
return [dPrev, x, y];
}
static modularInverse(a, m) {
const [gcd, x, _] = this.gcdExtended(a, m);
return gcd !== 1n ? null : ((x.get() % m) + m) % m; // x.get() % m might be negative
}
static chineseRemainderTheorem(pairs) {
const modulo = BigInt(pairs.reduce((acc, curr) => acc * curr.m, 1)); // modules product
let x = 0n;
for (const { a, m } of pairs) {
const mi = modulo / m;
const inv = this.modularInverse(mi, BigInt(m));
if (inv === null) {
return null;
}
x += a * mi * inv;
}
return ((x % modulo) + modulo) % modulo;
}
static solveLinearDiophantine(a, b, c) {
const [d, x0, y0] = this.gcdExtended(a, b);
if (c % d !== 0n) {
return null;
}
const multiplier = c / d;
const x = x0.get() * multiplier;
const y = y0.get() * multiplier;
return [x, y];
}
static phiInterval(value, start, end) {
const startValue = BigInt(Math.min(Number(start), Number(end)));
let endValue = BigInt(Math.max(Number(start), Number(end)));
if (value === endValue) {
--endValue;
}
const values = [];
for (let i = startValue; i <= endValue; ++i) {
if (this.modularInverse(i, value) !== null) {
values.push(i);
}
}
return values;
}
static phi(value) {
return this.phiInterval(value, 1n, value - 1n).length;
}
}
exports.EuclidClass = EuclidClass;