JSFiddle - React, Tailwind, and code Playground
JavaScript
function eratosthenesWithPi(n) {
let array = [], upperLimit = Math.sqrt(n), output = [];
let pi = [0, 0]
for (let i = 0; i < n; i++) {
array.push(true);
}
for (let i = 2; i <= upperLimit; i++) {
if (array[i]) {
for (var j = i * i; j < n; j += i) {
array[j] = false;
}
}
}
let cnt = 0
for (let i = 2; i < n; i++) {
if (array[i]) {
output.push(i);
cnt++
}
pi.push(cnt)
}
return {primes: new Uint32Array(output), pi: new Uint32Array(pi)}
}
const phiMemo = []
let primes = []
function Phi(m, b) {
if (b === 0)
return m
if (m === 0)
return 0
if (m >= 800) {
return Phi(m, b - 1) - Phi(Math.floor(m / primes[b - 1]), b - 1)
}
let t = b * 800 + m
if (!phiMemo[t]) {
phiMemo[t] = Phi(m, b - 1) - Phi(Math.floor(m / primes[b - 1]), b - 1)
}
return phiMemo[t]
}
const smallValues = [0, 0, 1, 2, 2, 3]
let piValues
function primeCountingFunction(x) {
if (x < 6)
return smallValues[x]
let root2 = Math.floor(Math.sqrt(x))
let root3 = Math.floor(x ** (1/3))
let top = Math.floor(x / root3) + 1
if (root2 + 1 >= primes.length) {
let res = eratosthenesWithPi(top + 2)
primes = res.primes
piValues = res.pi
}
let a = piValues[root3 + 1], b = piValues[root2 + 1]
let sum = 0
for (let i = a; i < b; ++i) {
let p = primes[i]
sum += piValues[Math.floor(x / p)] - piValues[p] + 1
}
let phi = Phi(x, a)
return phi + a - 1 - sum
}
console.log(primeCountingFunction(1e8))