JSFiddle - React, Tailwind, and code Playground

JavaScript

function factorial(n) {
    return _factorial(n, primes(n))
}

function _factorial(n, primes) {
    if (n < 2) return 1

    const factorialNumber = _factorial(Math.floor(n / 2), primes)
    const primeSwingNumber = primeSwing(n, primes)

    return factorialNumber ** 2 * primeSwingNumber
}

function primeSwing(n, primes) {
    const multipliers = []

    for (let i = 0; i < primes.length && primes[i] <= n; i++) {
        const prime = primes[i]

        let p = 1

        let q = n

        while (q !== 0) {
            q = Math.floor(q / prime)

            if (q % 2 === 1) {
                p = p * prime
            }
        }

        if (p !== 1) {
            multipliers.push(p)
        }
    }

    return product(multipliers, 0, multipliers.length - 1)
}

function product(multipliers, i, j) {
    if (i > j) return 1
    if (i === j) return multipliers[i]

    let k = (i + j) >>> 1

    return product(multipliers, i, k) * product(multipliers, k + 1, j)
}

function primes(upTo) {
    upTo++

    if (upTo >= 0 && upTo < 3) return []

    let length = upTo >>> 1

    const sieve_bool = Array.from({
        length
    }, () => false)

    for (let i = 1, iterations = Math.sqrt(length - 1); i < iterations; i++) {
        if (!sieve_bool[i]) {
            for (let step = 2 * i + 1, j = i * (step + 1); j < length; j += step) {
                sieve_bool[j] = true
            }
        }
    }

    let not_primes = 0

    for (let not_prime of sieve_bool) {
        if (not_prime) not_primes++
    }

    let sieve_int = Array(length - not_primes)

    sieve_int[0] = 2

    for (let i = 1, j = 1; i < length; i++) {
        if (!sieve_bool[i]) {
            sieve_int[j++] = 2 * i + 1
        }
    }

    return sieve_int
}

console.log(factorial(5))