Sum of factorial in a specific range

Asked

Viewed 515 times

5

I need to add the factors from 1 to 10, but I have not found the best way to implement this function.

def soma_fatorial():
    resultado = 1
    for i in range(1, 11):
        resultado = resultado * i
    return resultado

3 answers

6

The factorial of a number n, for definition is the product of all numbers starting with n until 1.

Well, to calculate the factorial of a number we can use the following code:

def fatorial(n):
    prod = 1
    for c in range(n, 0, -1):
        prod *= c
    return prod


num = int(input('Digite um número inteiro: '))

print(fatorial(num))

Now, from what I understand of your statement you want to calculate the sum of all the factorial 1 until n.

1st way to solve:

To calculate this sum we must use the following code:

def soma_fatorial(n):
    soma = 0
    for c in range(1, n + 1):
        prod = 1
        for d in range(c, 0, -1):
            prod *= d
        soma += prod
    return soma


num = int(input('Digite um número: '))

print(soma_fatorial(num))

Note in this second code that the first for of function soma_fatorial traverses the range of numbers we wish to calculate their factorial and the last for calculates the factorial of the respective iteration.

Let’s test the code:

Example 1

Calculate the sum of the factors of 1 until 3

In this case, we execute the code and when we receive the message; Digite um número, We must enter the upper limit, which in this case is 3. Then we receive the following output:

9

For 9 = 1! + 2! + 3! = 1 + 2 + 6 = 9

Example 2

Calculate the sum of the factors of 1 until 10

In this case, we execute the code and when we receive the message; Digite um número, We must enter the upper limit, which in this case is 10. Then we receive the following output:

4037913

For 4037913 = 1! + 2! + 3! + 4! + 5! + 6! + 7! + 8! + 9! + 10! = 4037913


2nd way to solve:

Another interesting way to resolve this issue is by using the method factorial library Math. That way, the solution would be:

from math import factorial


def soma_fatorial(n):
    soma = 0
    for c in range(1, n + 1):
        soma += factorial(c)
    return soma


num = int(input('Digite um número: '))

print(soma_fatorial(num))

3rd Way to solve:

This issue can also be resolved by list comprehension. In this case, the resolution would be:

from math import factorial


def soma_fatorial(n):
    return sum([factorial(c) for c in range(1, n + 1)])


num = int(input('Digite um número: '))

print(soma_fatorial(num))

4th Way to solve:

Another thing, you can resolve this issue without utilise def functions. For that you would use only 2 lines of code. In this case the solution would be:

from math import factorial

print(sum([factorial(c) for c in range(1, int(input('Digite um número: ')) + 1)]))

4

Making a loop that traverses the numbers from 1 to n by calculating the factorial of each separately may not be a good idea (except when n=51), unless you have implemented some layer of memoization, which was not the case with the other replies (1 and 2).

Knowing that n! = n*(n-1)! the sum of the factorial is:

S = 1! + 2! + 3! + ... + n!
S = 1! + 2*1! + 3*2*1! + ... + n*(n-1)*(n-2)*...*3*2*1!
S = 1! * (1 + 2 + 3*2 + ... + n*(n-1)*(n-2)*...*3*2)
S = 1! * (1 + 2 * (1 + 3 * (1 + 4 * (... + (n-1) * (1 + n))))

That is, to calculate the factorial of the next number just multiply it by the factorial of the previous number. For the sum of them, just accumulate all these values in the form of addition.

def soma_fatorial(n):
    soma = 0
    fatorial = 1
    for numero in range(1, n+1):
      fatorial = numero * fatorial
      soma += fatorial
    return soma

print(soma_fatorial(10))  # 4037913

This reduces the complexity of your algorithm from O(n²) to O(n).


You can still improve the solution with separation of responsibilities using generators, as I showed in this answer:

def fatorial_range(n):
    """ Retorna o fatorial de todos os números entre 1 e n """
    next_value = 1
    for i in range(1, n+1):
        yield next_value
        next_value *= i + 1

print(sum(fatorial_range(10)))  # 4037913

3

As I didn’t notice any prerequisite in the question. I believe that the most direct way would be to use Python resources for this. In this case the recursion.

>>> def fatorial(n):
...     if n == 0:
...         return 1
...     return n * fatorial(n - 1)
...
>>> fatorial(0)
1
>>> fatorial(1)
1
>>> fatorial(5)
120

Therefore, to take the sum of the factorials of a specific range, would suffice

>>> sum([fatorial(s) for s in range(2, 6)])
152

Note: The command range Python takes the initial number to one before the final number. That is, in the example above 2 to 5

fatorial de 2 = 2
fatorial de 3 = 6
fatorial de 4 = 24
fatorial de 5 = 120

The sum of all 152

Update: This form allows you to add factorials of non-sequential numbers. In the example below the sum of the factorials of 2, 3, 5 and 8.

>>> sum([fatorial(s) for s in [2, 3, 5, 8]])
40448

I hope I have help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.