function factorial(n) {
    // Base case: factorial of 0 or 1 is 1
    if (n === 0 || n === 1) {
        return 1;
    } else {
        // Recursive case: n! = n * (n-1)!
        return n * factorial(n - 1);
    }
}

// Example usage:
const result = factorial(5);
console.log(result);  // Output: 120


function factorialIterative(n) {
    let result = 1;
    for (let i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
}
const result1 = factorialIterative(6);
console.log(result1);  // Output: 720


function factorialTernary(n) {
    return (n === 0 || n === 1) ? 1 : n * factorialTernary(n - 1);
}

const result2 = factorialTernary(4);
console.log(result2);  // Output: 24

function factorialWhileLoop(n) {
    let result = 1;
    while (n > 1) {
        result *= n;
        n--;
    }
    return result;
}

const result3 = factorialWhileLoop(4);
console.log(result3);  // Output: 24


const factorialES6 = n => (n === 0 || n === 1) ? 1 : n * factorialES6(n - 1);
const result4 = factorialES6(5);
console.log(result4);  // Output: 120


const factorialES6Iterative = (n, result = 1) => {
    for (let i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
};

const result5 = factorialES6Iterative(5);
console.log(result5);  // Output: 120

const factorialES6Reduce = n => [...Array(n).keys()].reduce((acc, val) => acc * (val + 1), 1);
const result6 = factorialES6Reduce(6);
console.log(result6); //720


const factorialMemoized = (function() {
    const memo = {};

    function factorial(n) {
        if (n === 0 || n === 1) {
            return 1;
        }

        // Check if the result is already memoized
        if (memo[n]) {
            return memo[n];
        }

        // Calculate and memoize the result
        memo[n] = n * factorial(n - 1);

        return memo[n];
    }

    return factorial;
})();

// Example usage:
const result7 = factorialMemoized(5);
console.log(result7);  // Output: 120


const factorialFunctional = n => Array.from({ length: n }, (_, i) => i + 1).reduce((acc, val) => acc * val, 1);
const result8 = factorialFunctional(5);
console.log(result8);  // Output: 120

//------------------------------------
const compose = (...functions) => input => functions.reduceRight((acc, fn) => fn(acc), input);

const range = n => Array.from({ length: n }, (_, i) => i + 1);
const multiply = (a, b) => a * b;

const factorialComplex = n => compose(
    result => console.log(result),  // Display the result (optional)
    numbers => numbers.reduce(multiply, 1),  // Multiply all numbers in the array
    range,  // Generate an array of numbers from 1 to n
)(n);
 
//-----------------------

const factorialUsingMap = n => {
    return Array.from({ length: n }, (_, i) => i + 1)
        .map(number => BigInt(number)) // Convert numbers to BigInt to handle larger factorials
        .reduce((acc, val) => acc * val, BigInt(1));
};

// Example usage:
const result9 = factorialUsingMap(5);
console.log(result9.toString());  // Output: 120

const factorialUsingIIFEES6 = ((n) => {
    const calculateFactorial = (num, result = BigInt(1)) => {
        if (num === 0 || num === 1) {
            return result;
        }
        return calculateFactorial(num - 1, result * BigInt(num));
    };

    return calculateFactorial(n);
})(5); // Pass the desired input to the IIFE

console.log(factorialUsingIIFEES6.toString());  // Output: 120

 
by