Code: Select all
TernaryI32 = (function () {
"use strict";
let MAX_VALUE = 926510094425920;
let MIN_VALUE = -926510094425920;
function ctor(value) {
let result = new.target ? this : Object.create(ctor.prototype);
if (value instanceof ctor) {
result.pos = value.pos;
result.neg = value.neg;
} else {
let pos = 0, neg = 0, rem;
value = Math.trunc(value);
if (!Number.isSafeInteger(value)) value = 0;
for (let i = 1; i && value; i <<= 1) {
rem = value % 3;
rem = (rem % 2 * 3 - rem) / 2;
if (rem > 0) pos += i;
if (rem < 0) neg += i;
value = (value - rem) / 3;
}
result.pos = pos;
result.neg = neg;
}
return result;
};
function abs(a) {
return sign(a) < 0 ? neg(a) : ctor(a);
};
function add(a, b) {
let pos_A = a.pos | 0;
let neg_A = a.neg | 0;
let pos_B = b.pos | 0;
let neg_B = b.neg | 0;
let pos_XOR = pos_A ^ pos_B;
let neg_XOR = neg_A ^ neg_B;
let t = pos_XOR & neg_XOR;
pos_XOR ^= t;
neg_XOR ^= t;
let pos_AND = pos_A & pos_B;
let neg_AND = neg_A & neg_B;
let pos_P = pos_XOR | pos_AND;
let neg_P = neg_XOR | neg_AND;
let pos_G = pos_XOR | neg_AND;
let neg_G = neg_XOR | pos_AND;
let pos_SUM = pos_G;
let neg_SUM = neg_G;
for (let step = 1; step <= 16; step += step) {
let pos_Pr = pos_P << step;
let neg_Pr = neg_P << step;
let pos_Gr = pos_G << step;
let neg_Gr = neg_G << step;
t = pos_Gr | neg_Gr;
pos_P &= pos_Pr | ~(pos_G | (neg_G & neg_Pr & ~t));
neg_P &= neg_Pr | ~(neg_G | (pos_G & pos_Pr & ~t));
t = (pos_G & pos_Pr) | (neg_G & neg_Pr);
pos_G = t & pos_Gr;
neg_G = t & neg_Gr;
}
pos_P <<= 1;
neg_P <<= 1;
pos_XOR = pos_P ^ pos_SUM;
pos_XOR = neg_P ^ neg_SUM;
t = pos_XOR & neg_XOR;
pos_AND = pos_P & pos_SUM;
neg_AND = neg_P & neg_SUM;
let result = Object.create(ctor.prototype);
result.pos = neg_AND | (pos_XOR ^ t);
result.neg = pos_AND | (neg_XOR ^ t);
return result;
};
function addcarry(a, b, cin) {
let t = addext(a, b);
a = t[0];
let cout = t[1];
if (cin > 0) {
b = inc(a);
if (a.pos === -1) cout = Math.min(cout, 0) + 1;
} else if (cin < 0) {
b = dec(a);
if (a.neg === -1) cout = Math.max(cout, 0) - 1;
} else {
b = a;
}
return [b, cout];
};
function addext(a, b) {
let sum = add(a, b);
let carry = sign(a);
if (carry !== sign(b) || carry === sign(sum)) carry = 0;
return [sum, carry];
};
function cast(value) {
return value instanceof ctor ? value : ctor(value);
};
function cldiv(a, b) {
return cldiv_i(a, b)[0];
};
function cldiv_i(a, b) {
let sign_B = sign(b);
if (sign_B < 0) {
a = neg(a); b = neg(b);
} else if (!sign_B) {
return null;
}
let exp_A = 31 - Math.clz32(a.pos | a.neg);
let exp_B = 31 - Math.clz32(b.pos | b.neg);
let pos_Q = 0;
let neg_Q = 0;
while (exp_A >= exp_B) {
let i = exp_A - exp_B;
if ((a.pos >> exp_A) & 1) {
a = tritsub(a, shift(b, i));
pos_Q |= 1 << i;
} else if ((a.neg >> exp_A) & 1) {
a = tritadd(a, shift(b, i));
neg_Q |= 1 << i;
}
exp_A--;
}
if (sign_B < 0) {
a = neg(a);
}
let q = Object.create(ctor.prototype);
q.pos = pos_Q;
q.neg = neg_Q;
return [q, a];
};
function clmul(a, b) {
if (((a.pos | a.neg) >>> 0) < ((b.pos | b.neg) >>> 0)) {
let t = a; a = b; b = t;
}
let pos_B = b.pos | 0;
let neg_B = b.neg | 0;
let both_B = pos_B | neg_B;
let result = ctor(0);
for (let i = 0; both_B; i++) {
let j = 1 << i;
if (both_B & j) {
both_B ^= j;
result = ((pos_B & j) ? tritadd : tritsub)(result, shift(a, i));
}
}
return result;
};
function clmulinv(a) {
let sign = a.neg & 1;
if (sign) {
a = neg(a);
} else if (!(a.pos & 1)) {
return null;
}
let b = ctor(1);
let pos_R = 0;
let neg_R = 0;
for (let i = 0; i < 32; i++) {
if (b.pos & 1) {
b = tritsub(b, a);
pos_R |= 1 << i;
} else if (b.neg & 1) {
b = tritadd(b, a);
neg_R |= 1 << i;
}
b = shift(b, -1);
}
if (sign) {
let t = pos_R; pos_R = neg_R; neg_R = t;
}
let result = Object.create(ctor.prototype);
result.pos = pos_R;
result.neg = neg_R;
return result;
};
function clpow(a, n) {
if (!(n >= 0 && n <= Number.MAX_SAFE_INTEGER)) {
return null;
}
let s = (a.pos & 1) - (a.neg & 1);
if (!s && n > 31) return ctor(0);
let b = [a, clmul(a, a)];
let r = n % 3;
let c = r ? b[r - 1] : ctor(1);
for (let step = 3; n = (n - r) / 3, n > 0 && step < 32; step *= 3) {
r = n % 3;
if (r) {
let d = b[r - 1];
let pos_D = d.pos | 0;
let neg_D = d.neg | 0;
let both_D = pos_D | neg_D;
let n = 32 / step;
a = ctor(0);
for (let i = 0; i < n && both_D; i++) {
let j = 1 << i;
if (both_D & j) {
both_D ^= j;
a = (pos_D & j ? tritadd : tritsub)(a, shift(c, i * step));
}
}
c = a;
}
}
if (s < 1 && n % 2) c = neg(c);
return c;
};
function clrem(a, b) {
return cldiv_i(a, b)[1];
};
function clz32(a) {
return Math.clz32(a.pos | a.neg);
};
function cmp(a, b) {
let pos_A = a.pos | 0;
let neg_A = a.neg | 0;
let pos_B = b.pos | 0;
let neg_B = b.neg | 0;
a = ((pos_A & ~pos_B) | (neg_B & ~neg_A)) >>> 0;
b = ((pos_B & ~pos_A) | (neg_A & ~neg_B)) >>> 0;
return Math.sign(a - b);
};
function ctz32(a) {
a = a.pos | a.neg;
return a ? 31 - Math.clz32(a & -a) : 32;
};
function dec(a) {
return neg(inc(neg(a)));
};
function div(a, b) {
let t = divrem_i(a, b);
return t && ctor(t[0]);
};
function divrem_i(a, b) {
b = valueOf(b);
if (!b) return null;
a = valueOf(a);
let r = a % b;
return [(a - r) / b, r];
};
function inc(a) {
let pos_A = a.pos | 0;
let neg_A = a.neg | 0;
let b = pos_A + 1;
let c = b & -b;
let result = Object.create(ctor.prototype);
result.pos = b & ~(neg_A & c);
result.neg = (neg_A & ~c) | (c - 1);
return result;
};
function max(a, b) {
return ctor(cmp(a, b) < 0 ? a : b);
};
function min(a, b) {
return ctor(cmp(a, b) > 0 ? a : b);
};
function mul(a, b) {
let pos_A = a.pos | 0;
let neg_A = a.neg | 0;
let pos_B = b.pos | 0;
let neg_B = b.neg | 0;
let hi_A = valueOf({pos: pos_A >>> 16, neg: neg_A >>> 16});
let lo_A = valueOf({pos: pos_A & 0xFFFF, neg: neg_A & 0xFFFF});
let hi_B = valueOf({pos: pos_B >>> 16, neg: neg_B >>> 16});
let lo_B = valueOf({pos: pos_B & 0xFFFF, neg: neg_B & 0xFFFF});
return ctor((hi_A * lo_B + hi_B * lo_A) % 43046721 * 43046721 + lo_A * lo_B);
};
function mulext(a, b) {
let pos_A = a.pos | 0;
let neg_A = a.neg | 0;
let pos_B = b.pos | 0;
let neg_B = b.neg | 0;
let hi_A = valueOf({pos: pos_A >>> 16, neg: neg_A >>> 16});
let lo_A = valueOf({pos: pos_A & 0xFFFF, neg: neg_A & 0xFFFF});
let hi_B = valueOf({pos: pos_B >>> 16, neg: neg_B >>> 16});
let lo_B = valueOf({pos: pos_B & 0xFFFF, neg: neg_B & 0xFFFF});
let hi_C = hi_A * hi_B;
let mi_C = hi_A * lo_B + hi_B * lo_A;
let lo_C = lo_A * lo_B;
let r = mi_C % 43046721;
lo_C += r * 43046721;
hi_C += (mi_C - r) / 43046721;
if (lo_C > MAX_VALUE) {
lo_C -= 1853020188851841;
hi_C ++;
} else if (lo_C < MIN_VALUE) {
lo_C += 1853020188851841;
hi_C --;
}
return [ctor(lo_C), ctor(hi_C)];
};
function mulinv(a) {
a = valueOf(a);
if (!(a % 3)) return null;
let x = a % 43046721;
let y = (1 - x * x) % 43046721;
while (y) {
x = x * (1 + y) % 43046721;
y = y * y % 43046721;
}
let lo = a % 43046721;
let hi = (a - lo) / 43046721;
return ctor(x + ((1 - lo * x) / 43046721 - hi * x % 43046721) * x % 43046721 * 43046721);
}
function nabs(a) {
return neg(abs(a));
};
function nadd(a, b) {
return neg(add(a, b));
};
function neg(a) {
let result = Object.create(ctor.prototype);
result.pos = a.neg;
result.neg = a.pos;
return result;
};
function nmax(a, b) {
return neg(max(a, b));
};
function nmin(a, b) {
return neg(min(a, b));
};
function nmul(a, b) {
return neg(mul(a, b));
};
function parity(a) {
a = a.neg | a.pos;
a ^= a >> 16;
a ^= a >> 8;
a ^= a >> 4;
return (0x6996 >> (a & 15)) & 1;
};
function pow(a, n) {
if (!(n >= 0 && n <= Number.MAX_SAFE_INTEGER)) {
return null;
}
let result = ctor(1);
while (n >= 1) {
if (n % 2 >= 1) {
result = mul(result, a);
}
a = mul(a, a);
n /= 2;
}
return result;
};
function rem(a, b) {
let t = divrem_i(a, b);
return t && ctor(t[1]);
};
function shift(a, n) {
let pos, neg;
if (n < -31 || n > 31) {
pos = neg = 0;
} else if (n < 0) {
pos = a.pos >>> (-n);
neg = a.neg >>> (-n);
} else {
pos = a.pos << n;
neg = a.neg << n;
}
let result = Object.create(ctor.prototype);
result.pos = pos;
result.neg = neg;
return result;
};
function sign(a) {
return Math.sign((a.pos >>> 0) - (a.neg >>> 0));
};
function sub(a, b) {
return add(a, neg(b));
};
function tritabs(a) {
let result = Object.create(ctor.prototype);
result.pos = a.pos | a.neg;
result.neg = 0;
return result;
};
function tritadd(a, b) {
let pos_A = a.pos | 0;
let neg_A = a.neg | 0;
let pos_B = b.pos | 0;
let neg_B = b.neg | 0;
let pos_XOR = pos_A ^ pos_B;
let neg_XOR = neg_A ^ neg_B;
let t = pos_XOR & neg_XOR;
let pos_AND = pos_A & pos_B;
let neg_AND = neg_A & neg_B;
let result = Object.create(ctor.prototype);
result.pos = neg_AND | (pos_XOR ^ t);
result.neg = pos_AND | (neg_XOR ^ t);
return result;
};
function tritany(a, b) {
let pos_OR = a.pos | b.pos;
let neg_OR = a.neg | b.neg;
let t = pos_OR & neg_OR;
let result = Object.create(ctor.prototype);
result.pos = pos_OR ^ t;
result.neg = neg_OR ^ t;
return result;
};
function tritcmp(a, b) {
return tritany(a, neg(b));
};
function tritcons(a, b) {
let result = Object.create(ctor.prototype);
result.pos = a.pos & b.pos;
result.neg = a.neg & b.neg;
return result;
};
function tritdec(a) {
return neg(tritinc(neg(a)));
};
function triteq(a, b) {
let neg = (a.pos ^ b.pos) | (a.neg ^ b.neg);
let result = Object.create(ctor.prototype);
result.pos = ~neg;
result.neg = neg;
return result;
};
function tritgt(a, b) {
return tritlt(b, a);
};
function tritgte(a, b) {
return neg(tritlt(a, b));
};
function tritinc(a) {
let pos_A = a.pos | 0;
let neg_A = a.neg | 0;
let result = Object.create(ctor.prototype);
result.pos = ~(pos_A | neg_A);
result.neg = pos_A;
return result;
};
function tritlt(a, b) {
let pos = (~a.pos & b.pos) | (a.neg & ~b.neg);
let result = Object.create(ctor.prototype);
result.pos = pos;
result.neg = ~pos;
return result;
};
function tritlte(a, b) {
return neg(tritlt(b, a));
};
function tritmax(a, b) {
let result = Object.create(ctor.prototype);
result.pos = a.pos | b.pos;
result.neg = a.neg & b.neg;
return result;
};
function tritmin(a, b) {
let result = Object.create(ctor.prototype);
result.pos = a.pos & b.pos;
result.neg = a.neg | b.neg;
return result;
};
function tritmul(a, b) {
let pos_A = a.pos | 0;
let neg_A = a.neg | 0;
let pos_B = a.pos | 0;
let neg_B = a.neg | 0;
let result = Object.create(ctor.prototype);
result.pos = (pos_A & pos_B) | (neg_A & neg_B);
result.neg = (pos_A & neg_B) | (neg_A & pos_B);
return result;
};
function tritnabs(a) {
return neg(tritabs(a));
};
function tritnadd(a, b) {
return neg(tritadd(a, b));
};
function tritneg(a) {
return tritpos(neg(a));
};
function tritneq(a, b) {
return neg(tritneq(a, b));
};
function tritnmax(a, b) {
return neg(tritmax(a, b));
};
function tritnmin(a, b) {
return neg(tritmin(a, b));
};
function tritnmul(a, b) {
return neg(tritmul(a, b));
};
function tritnneg(a) {
return neg(tritneg(a));
};
function tritnpos(a) {
return neg(tritpos(a));
};
function tritnzero(a) {
return neg(tritzero(a));
};
function tritpos(a) {
a = a.pos;
let result = Object.create(ctor.prototype);
result.pos = a;
result.neg = ~a;
return result;
};
function tritsub(a, b) {
return tritadd(a, neg(b));
};
function tritzero(a) {
a = a.pos | a.neg;
let result = Object.create(ctor.prototype);
result.pos = ~a;
result.neg = a;
return result;
};
function toBalanced(a, tab) {
let pos_A = a.pos;
let neg_A = a.neg;
let result = "";
for (let i = 1 << 31; i; i >>>= 1) {
result += tab[(pos_A & i) ? 2 : +!(neg_A & i)];
}
return result;
};
function valueOf(a) {
let pos = a.pos | 0;
let neg = a.neg | 0;
let result = 0;
for (let i = 1; pos || neg; i *= 3) {
result += i * ((pos & 1) - (neg & 1));
pos >>>= 1;
neg >>>= 1;
}
return result;
};
ctor.MAX_VALUE = Object.freeze(ctor(MAX_VALUE));
ctor.MIN_VALUE = Object.freeze(ctor(MIN_VALUE));
ctor.ZERO = Object.freeze(ctor(0));
ctor.abs = function(a, b) { return abs(cast(a)); };
ctor.add = function(a, b) { return add(cast(a), cast(b)); };
ctor.addcarry = function(a, b, c) { return addcarry(cast(a), cast(b), +c); };
ctor.addext = function(a, b) { return addext(cast(a), cast(b)); };
ctor.cast = cast;
ctor.cldiv = function(a, b) { return cldiv(cast(a), cast(b)); };
ctor.clmul = function(a, b) { return clmul(cast(a), cast(b)); };
ctor.clmulinv = function(a) { return clmulinv(cast(a)); };
ctor.clpow = function(a, b) { return clpow(cast(a), Math.trunc(b)); };
ctor.clrem = function(a, b) { return clrem(cast(a), cast(b)); };
ctor.clz32 = function(a) { return clz32(cast(a)); };
ctor.cmp = function(a, b) { return cmp(cast(a), cast(b)); };
ctor.ctz32 = function(a) { return ctz32(cast(a)); };
ctor.dec = function(a, b) { return dec(cast(a)); };
ctor.div = function(a, b) { return div(cast(a), cast(b)); };
ctor.eq = function(a, b) { return !cmp(cast(a), cast(b)); };
ctor.gt = function(a, b) { return cmp(cast(a), cast(b)) > 0; };
ctor.gte = function(a, b) { return cmp(cast(a), cast(b)) >= 0; };
ctor.inc = function(a, b) { return inc(cast(a)); };
ctor.iseven = function(a) { return !parity(cast(a)); };
ctor.isneg = function(a) { return sign(cast(a)) < 0; };
ctor.isodd = function(a) { return !!parity(cast(a)); };
ctor.ispos = function(a) { return sign(cast(a)) > 0; };
ctor.iszero = function(a) { return !sign(cast(a)); };
ctor.lt = function(a, b) { return cmp(cast(a), cast(b)) < 0; };
ctor.lte = function(a, b) { return cmp(cast(a), cast(b)) <= 0; };
ctor.max = function(a) { return max(cast(a), cast(b)); };
ctor.min = function(a) { return min(cast(a), cast(b)); };
ctor.mul = function(a, b) { return mul(cast(a), cast(b)); };
ctor.mulext = function(a, b) { return mulext(cast(a), cast(b)); };
ctor.mulinv = function(a) { return mulinv(cast(a)); };
ctor.nabs = function(a) { return nabs(cast(a)); };
ctor.nadd = function(a, b) { return nadd(cast(a), cast(b)); };
ctor.neg = function(a) { return neg(cast(a)); };
ctor.neq = function(a, b) { return !!cmp(cast(a), cast(b)); };
ctor.nmax = function(a, b) { return nmax(cast(a, b)); };
ctor.nmin = function(a, b) { return nmin(cast(a, b)); };
ctor.nmul = function(a, b) { return nmul(cast(a, b)); };
ctor.pow = function(a, b) { return pow(cast(a), Math.trunc(b)); };
ctor.rem = function(a, b) { return rem(cast(a), cast(b)); };
ctor.shift = function(a, n) { return shift(cast(a), Math.trunc(n)); };
ctor.sign = function(a) { return sign(cast(a)); };
ctor.sub = function(a, b) { return sub(cast(a), cast(b)); };
ctor.tritabs = function(a) { return tritabs(cast(a)); };
ctor.tritadd = function(a, b) { return tritadd(cast(a), cast(b)); };
ctor.tritany = function(a, b) { return tritany(cast(a), cast(b)); };
ctor.tritcmp = function(a, b) { return tritcmp(cast(a), cast(b)); };
ctor.tritcons = function(a, b) { return tritcons(cast(a), cast(b)); };
ctor.tritdec = function(a) { return tritdec(cast(a)); };
ctor.triteq = function(a, b) { return triteq(cast(a), cast(b)); };
ctor.tritgt = function(a, b) { return tritgt(cast(a), cast(b)); };
ctor.tritgte = function(a, b) { return tritgte(cast(a), cast(b)); };
ctor.tritinc = function(a) { return tritinc(cast(a)); };
ctor.tritlt = function(a, b) { return tritlt(cast(a), cast(b)); };
ctor.tritlte = function(a, b) { return tritlte(cast(a), cast(b)); };
ctor.tritmax = function(a, b) { return tritmax(cast(a), cast(b)); };
ctor.tritmin = function(a, b) { return tritmin(cast(a), cast(b)); };
ctor.tritmul = function(a, b) { return tritmul(cast(a), cast(b)); };
ctor.tritnabs = function(a, b) { return tritnabs(cast(a), cast(b)); };
ctor.tritnadd = function(a, b) { return tritnadd(cast(a), cast(b)); };
ctor.tritneg = function(a) { return tritneg(cast(a)); };
ctor.tritneq = function(a, b) { return tritneq(cast(a), cast(b)); };
ctor.tritnmax = function(a, b) { return tritnmax(cast(a), cast(b)); };
ctor.tritnmin = function(a, b) { return tritnmin(cast(a), cast(b)); };
ctor.tritnmul = function(a, b) { return tritnmul(cast(a), cast(b)); };
ctor.tritnneg = function(a) { return tritnneg(cast(a)); };
ctor.tritnpos = function(a) { return tritnpos(cast(a)); };
ctor.tritnzero = function(a) { return tritnzero(cast(a)); };
ctor.tritpos = function(a) { return tritpos(cast(a)); };
ctor.tritsub = function(a, b) { return tritsub(cast(a), cast(b)); };
ctor.tritzero = function(a) { return tritzero(cast(a)); };
ctor.prototype.toBalanced = function(tab) { return toBalanced(this, String(tab == null ? "T01" : tab).split("")); };
ctor.prototype.toString = function(radix) { return valueOf(this).toString(radix); };
ctor.prototype.valueOf = function() { return valueOf(this); };
return ctor;
})();