def find_duplicate_number(array):
    """
    We know that we will be given a series of numbers [0, n-2] with one extra number (the duplicate number)
    so if we take the total sum of series [0, n-2] (arithmetic series sum = n((a1 + an)/2) ) and extract it
    from actual sum of the array we we will get the extra number
    :param array:
    :return: duplicate number
    """

    # total terms
    n = ((len(array)-2) + 1) # +1 to include 0 as the range is [0, n-2] with 0 inclusive
    # first term
    a1 = 0
    # last term
    an = len(array)-2
    # arithmetic series total sum = n((a1 + an)/2
    expected_sum = n * (a1 + an) / 2
    actual_sum = sum(array) # this will be greater than expected sum as there is an extra duplicate number
    return actual_sum - expected_sum