Hey, we are going to find an exciting number called Catalan number which is use to find the number of possible binary search trees from tree of a given number of nodes. We will use the formula: tn  SUMMATIONi  1 to nti1tni Further details at Wikipedia: https:en.wikipedia.orgwikiCatalannumber Our Contribution: Basically we Create the 2 function: 1. catalannumbernodecount: int  int Returns the number of possible binary search trees for n nodes. 2. binarytreecountnodecount: int  int Returns the number of possible binary trees for n nodes. Since Here we Find the Binomial Coefficient: https:en.wikipedia.orgwikiBinomialcoefficient Cn,k  n!  k!nk! :param n: 2 times of Number of nodes :param k: Number of nodes :return:  Integer Value  binomialcoefficient4, 2 6 Since Cn, k  Cn, nk Calculate Cn,k We can find Catalan number many ways but here we use Binomial Coefficient because it does the job in On return the Catalan number of n using 2nCnn1. :param n: number of nodes :return: Catalan number of n nodes  catalannumber5 42  catalannumber6 132 Return the factorial of a number. :param n: Number to find the Factorial of. :return: Factorial of n.  import math  allfactoriali  math.factoriali for i in range10 True  factorial5   doctest: ELLIPSIS Traceback most recent call last: ... ValueError: factorial not defined for negative values Return the number of possible of binary trees. :param n: number of nodes :return: Number of possible binary trees  binarytreecount5 5040  binarytreecount6 95040
"""
Our Contribution:
Basically we Create the 2 function:
    1. catalan_number(node_count: int) -> int
        Returns the number of possible binary search trees for n nodes.
    2. binary_tree_count(node_count: int) -> int
        Returns the number of possible binary trees for n nodes.
"""


def binomial_coefficient(n: int, k: int) -> int:
    """
    Since Here we Find the Binomial Coefficient:
    https://en.wikipedia.org/wiki/Binomial_coefficient
    C(n,k) = n! / k!(n-k)!
    :param n: 2 times of Number of nodes
    :param k: Number of nodes
    :return:  Integer Value

    >>> binomial_coefficient(4, 2)
    6
    """
    result = 1  # To kept the Calculated Value
    # Since C(n, k) = C(n, n-k)
    if k > (n - k):
        k = n - k
    # Calculate C(n,k)
    for i in range(k):
        result *= n - i
        result //= i + 1
    return result


def catalan_number(node_count: int) -> int:
    """
    We can find Catalan number many ways but here we use Binomial Coefficient because it
    does the job in O(n)

    return the Catalan number of n using 2nCn/(n+1).
    :param n: number of nodes
    :return: Catalan number of n nodes

    >>> catalan_number(5)
    42
    >>> catalan_number(6)
    132
    """
    return binomial_coefficient(2 * node_count, node_count) // (node_count + 1)


def factorial(n: int) -> int:
    """
    Return the factorial of a number.
    :param n: Number to find the Factorial of.
    :return: Factorial of n.

    >>> import math
    >>> all(factorial(i) == math.factorial(i) for i in range(10))
    True
    >>> factorial(-5)  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
    ValueError: factorial() not defined for negative values
    """
    if n < 0:
        raise ValueError("factorial() not defined for negative values")
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result


def binary_tree_count(node_count: int) -> int:
    """
    Return the number of possible of binary trees.
    :param n: number of nodes
    :return: Number of possible binary trees

    >>> binary_tree_count(5)
    5040
    >>> binary_tree_count(6)
    95040
    """
    return catalan_number(node_count) * factorial(node_count)


if __name__ == "__main__":
    node_count = int(input("Enter the number of nodes: ").strip() or 0)
    if node_count <= 0:
        raise ValueError("We need some nodes to work with.")
    print(
        f"Given {node_count} nodes, there are {binary_tree_count(node_count)} "
        f"binary trees and {catalan_number(node_count)} binary search trees."
    )
