52 lines
1.9 KiB
JavaScript
52 lines
1.9 KiB
JavaScript
const TinyPhiPrimes = [ 2, 3, 5, 7, 11, 13 ];
|
|
const TinyPhiOddDegree = TinyPhiPrimes.length - 1;
|
|
const TinyPhiOddCirc = TinyPhiPrimes.reduce((acc, p) => acc * p) / 2;
|
|
const TinyPhiTot = TinyPhiPrimes.reduce((acc, p) => acc * (p - 1), 1)
|
|
const TinyPhiLUT = function() {
|
|
const arr = new Uint16Array(TinyPhiOddCirc); arr.fill(1);
|
|
for (const p of TinyPhiPrimes) {
|
|
if (p <= 2) continue; arr[p >> 1] = 0;
|
|
for (let c = (p * p) >> 1; c < TinyPhiOddCirc; c += p) arr[c] = 0 >>> 0; }
|
|
for (let i = 0 | 0, acc = 0 | 0; i < TinyPhiOddCirc; ++i) {
|
|
acc += arr[i]; arr[i] = acc; }
|
|
return arr; }();
|
|
function tinyPhi(x) {
|
|
const ndx = Math.trunc(( x - 1) / 2);
|
|
const numtots = Math.trunc(ndx / TinyPhiOddCirc);
|
|
const rem = (ndx - numtots * TinyPhiOddCirc) >>> 0;
|
|
return numtots * TinyPhiTot + TinyPhiLUT[rem];
|
|
}
|
|
|
|
function countPrimesTo(lmt) {
|
|
if (lmt < 169) {
|
|
if (lmt < 3) { if (lmt < 2) return 0; else return 1; }
|
|
// adjust for the missing "degree" base primes
|
|
if (lmt <= 13) return ((lmt - 1) >>> 1) + (lmt < 9 ? 1 : 0);
|
|
return 5 + TinyPhiLUT[(lmt - 1) >>> 1];
|
|
}
|
|
const sqrtlmt = Math.sqrt(lmt) >>> 0;
|
|
const oprms = function() {
|
|
const mxndx = (sqrtlmt - 3) >>> 1;
|
|
const arr = new Float64Array(mxndx + 1);
|
|
for (let i = 0 >>> 0; i <= mxndx; ++i) arr[i] = (i + i + 3) >>> 0;
|
|
let bp = 3 >>> 0;
|
|
while (true) {
|
|
let i = (bp - 3) >>> 1; let sqri = ((i + i) * (i + 3) + 3) >>> 0;
|
|
if (sqri > mxndx) break;
|
|
if (arr[i] != 0) for (; sqri <= mxndx; sqri += bp) arr[sqri] = 0;
|
|
bp += 2;
|
|
}
|
|
return arr.filter(v => v != 0); }();
|
|
function lvl(pilmt, m) {
|
|
let ans = 0;
|
|
for (let pi = TinyPhiOddDegree; pi < pilmt; ++pi) {
|
|
const p = oprms[pi]; const nm = m * p;
|
|
if (lmt <= nm * p) return ans + pilmt - pi;
|
|
ans += tinyPhi(Math.trunc(lmt / nm));
|
|
if (pi > TinyPhiOddDegree) ans -= lvl(pi, nm);
|
|
}
|
|
return ans;
|
|
}
|
|
return tinyPhi(lmt) - lvl(oprms.length, 1) + oprms.length;
|
|
}
|