Factorial Digit Sum
n! significa n x (n - 1) x ... x 3 x 2 x 1
Por ejemplo, 10! = 10 x 9 x ... x 3 x 2 x 1 = 3628800,
y la suma de los dígitos de 10! es 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
Encuentra la suma de los dígitos de 100!
1 ¿Que es un factorial?
El factorial de un numero n, escrito como n!, es el producto de todos los enteros positivos desde 1 hasta n.
Visualizando 5!
El crecimiento explosivo del factorial
| n | n! | Digitos |
|---|---|---|
| 5 | 120 | 3 |
| 10 | 3,628,800 | 7 |
| 15 | 1,307,674,368,000 | 13 |
| 20 | 2,432,902,008,176,640,000 | 19 |
| 50 | 3.04 x 10^64 | 65 |
| 100 | 9.33 x 10^157 | 158 |
100! tiene 158 digitos. Es un numero ENORME, pero Python lo maneja sin problemas.
Factorial vs Potencia: ¿Cual crece mas rapido?
Potencia (2^n)
Factorial (n!)
El factorial crece mucho mas rapido. Ya en n=100, el factorial tiene 158 digitos mientras que 2^100 "solo" tiene 31 digitos.
100! completo (158 digitos)
Observa los muchos ceros al final. Cada vez que multiplicamos por un multiplo de 5 y de 2, anadimos un cero. Hay 24 ceros al final de 100!
¿Por que tantos ceros al final?
Cada cero al final viene de un factor 10 = 2 x 5.
Multiplos de 5 en 1-100: 5, 10, 15, 20, 25... = 20 numeros
Multiplos de 25 (dan 5 extra): 25, 50, 75, 100 = 4 numeros
Total de factores 5: 20 + 4 = 24
Hay muchos mas factores 2 que 5, asi que el limitante son los 5. Por eso 100! termina en exactamente 24 ceros.
Ejemplo: suma de digitos de 10!
Conexion con el Problema 16
Este problema es muy similar al Problema 16 (Power Digit Sum). La unica diferencia es que ahi calculabamos 2^1000 y aqui calculamos 100!
El algoritmo es identico: calcular el numero grande, convertir a string, sumar digitos. Python maneja ambos casos automaticamente con enteros de precision arbitraria.
2 Implementacion en Python
Python tiene la funcion math.factorial() integrada, pero tambien
podemos implementarlo nosotros mismos para entender mejor.
Iterativo vs Recursivo
Iterativo (preferido)
- Sin limite de profundidad
- Usa memoria constante
- Mas rapido en Python
Recursivo
- Limite ~1000 llamadas en Python
- Crea n stack frames
- Elegante pero ineficiente
La solucion en una linea
import math; print(sum(int(d) for d in str(math.factorial(100))))
O sin importar:
from functools import reduce
print(sum(int(d) for d in str(reduce(lambda a,b: a*b, range(1,101)))))
Resumen de metodos
| Metodo | Codigo | Nota |
|---|---|---|
| math.factorial | math.factorial(100) | Recomendado |
| Bucle for | resultado *= i | Educativo |
| Recursion | n * factorial(n-1) | Limite stack |
| reduce | reduce(lambda...) | Funcional |