In python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
import time
def RaiseToPower(x,thePower):
if thePower<4:
return x**thePower
result=1
squares=x;
while thePower>0 :
if (thePower%2)==1:
result=squares*result
squares=squares*squares
thePower = thePower/2
return result
def findAllPrimes(n):
x=[0]*n
y=[]
for i in range(2,n):
if x[i]==0:
for j in range(2*i,n,i):
x[j]=1
y.append(i)
return y
def factorial(n):
allprimesBelowN=findAllPrimes(n)
result=1
for i in range(0, len(allprimesBelowN)):
thePowerOfThePrime=0
currentPower=allprimesBelowN[i]
thePowerOfThePrime+=n/currentPower
while (currentPower<=n):
currentPower*= allprimesBelowN[i]
thePowerOfThePrime+=n/currentPower
result=result*(RaiseToPower(allprimesBelowN[i],thePowerOfThePrime))
return result
x=50000
t1=time.time()
print x, "! equals: ", factorial(x)
t2=time.time()
print "total running time raising powers by primes: ", t2-t1, " seconds"
|
output:
total running time raising powers by primes: 20.7800540924 seconds
and the straighforward method:
1 2 3 4 5 6 7 8 9 10 11
|
import time
x=50000
def factorial_straighforward(n):
result=1
for i in range(1, n+1):
result=result*i
return result
t1=time.time()
print x, "! equals: ", factorial_straighforward(x)
t2=time.time()
print "total running time using the straightforward method: ", (t2-t1), " seconds"
|
output:
total running time using the straightforward method: 27.1603929996 seconds
Alright, that was an equivalent of what I wrote in C++ in Python (this is my first Python program hehe - my mistake made me embarass myself, but also learn "Hello world" in Python :). The second factorial is the straightforward implementation, and the first factorial is the implementation with sorting out by primes and raising to powers like I did it originally.
However, I think that
x**y
does the same as my by-hand implementation
RaiseToPower(x,thePower)
, so I doubt I gain any speed there.
[Edit:] Indeed, the two programs
1 2 3 4 5
|
import time
t1=time.time()
print 7, "^ 100000 equals: ", 7**100000
t2=time.time()
print "total running time: ", t2-t1, " seconds"
|
and
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
import time
def RaiseToPower(x,thePower):
if thePower<4:
return x**thePower
result=1
squares=x;
while thePower>0 :
if (thePower%2)==1:
result=squares*result
squares=squares*squares
thePower = thePower/2
return result
t1=time.time()
print 7, "^ 100000 equals: ", RaiseToPower(7,100000)
t2=time.time()
print "total running time: ", t2-t1, " seconds"
|
showed practically the same time.
So, the simpler version of the factorial computed and printed to the screen 100 000! in 1 minute and 40 seconds 50000! in . The one based on the same tricks as my original c++ program runs in 1 minute 10 seconds.
The two factorials practically run at the same speed (maybe some 20-30% better by sorting out the prime powers first ), so for so much code, I guess it is not worth it at all.
Oh well, this taught me a lesson to first check out the easy stuff :). Also, when trying to translate the monstrous
RaiseToPower
from C++ to python , I figured out all my code distills down to the above short and sweet realization (will translate back to C++ now) .... oh well :)