Pitão
Abaixo está uma versão Python da solução, que não se limita ao limite de 32 bits (ou 64 bits em um sistema muito recente) para números inteiros no Python. Para contornar essa limitação, devemos usar uma string como entrada e saída para a
factorial
rotina e dividir internamente a string em seus dígitos para poder executar a multiplicação.
Então, aqui está o código: a getDigits
função divide uma string que representa um número em seus dígitos, de forma que "1234" se torna [ 4, 3, 2, 1 ]
(a ordem inversa apenas simplifica as funções increase
e multiply
). A increase
função pega essa lista e aumenta em um. Como o nome sugere, a multiply
função se multiplica, por exemplo, multiply([2, 1], [3])
retorna [ 6, 3 ]
porque 12 vezes 3 é 36. Isso funciona da mesma maneira que você multiplicaria algo com caneta e papel.
Finalmente, a factorial
função usa essas funções auxiliares para calcular o fatorial real, por exemplo, factorial("9")
fornece "362880"
como saída.
import copy
def getDigits(n):
digits = []
for c in n:
digits.append(ord(c) - ord('0'))
digits.reverse()
return digits
def increase(d):
d[0] += 1
i = 0
while d[i] >= 10:
if i == len(d)-1:
d.append(0)
d[i] -= 10
d[i+1] += 1
i += 1
def multiply(a, b):
subs = [ ]
s0 = [ ]
for bi in b:
s = copy.copy(s0)
carry = 0
for ai in a:
m = ai * bi + carry
s.append(m%10)
carry = m//10
if carry != 0:
s.append(carry)
subs.append(s)
s0.append(0)
done = False
res = [ ]
termsum = 0
pos = 0
while not done:
found = False
for s in subs:
if pos < len(s):
found = True
termsum += s[pos]
if not found:
if termsum != 0:
res.append(termsum%10)
termsum = termsum//10
done = True
else:
res.append(termsum%10)
termsum = termsum//10
pos += 1
while termsum != 0:
res.append(termsum%10)
termsum = termsum//10
return res
def factorial(x):
if x.strip() == "0" or x.strip() == "1":
return "1"
factorial = [ 1 ]
done = False
number = [ 1 ]
stopNumber = getDigits(x)
while not done:
if number == stopNumber:
done = True
factorial = multiply(factorial, number)
increase(number)
factorial.reverse()
result = ""
for c in factorial:
result += chr(c + ord('0'))
return result
print factorial("9")
Notas
No python, um número inteiro não tem um limite; portanto, se você quiser fazer isso manualmente, basta
fac = 1
for i in range(2,n+1):
fac *= i
Há também a math.factorial(n)
função muito conveniente .
Essa solução é obviamente muito mais complexa do que precisa, mas funciona e, de fato, ilustra como você pode calcular o fatorial no caso de você estar limitado por 32 ou 64 bits. Portanto, embora ninguém acredite que esta é a solução que você encontrou para esse problema simples (pelo menos em Python), você pode realmente aprender alguma coisa.