2014-06-12 138 views
-3

我知道這個代碼是醜陋的,但我想知道是否有人能告訴我一個方法來確定這樣的階乘在python:Python和與分數階乘

import math 

print(math.factorial(6400001)/(math.factorial(1) * math.factorial(103040) 
    * math.factorial(181760) * math.factorial(48000) * math.factorial(119040) 
    * math.factorial(78080) * math.factorial(64000) * math.factorial(163840) 
    * math.factorial(140160) * math.factorial(185600) * math.factorial(255360) 
    * math.factorial(131840) * math.factorial(109440) * math.factorial(104960) 
    * math.factorial(144000) * math.factorial(104320) * math.factorial(69120) 
    * math.factorial(96000) * math.factorial(67200) * math.factorial(49280) 
    * math.factorial(138240) * math.factorial(103040) * math.factorial(154240) 
    * math.factorial(206080) * math.factorial(49920) * math.factorial(126720) 
    * math.factorial(254720) * math.factorial(83200) * math.factorial(48000) 
    * math.factorial(80640) * math.factorial(142080) * math.factorial(124800) 
    * math.factorial(106880) * math.factorial(170880) * math.factorial(128640) 
    * math.factorial(44160) * math.factorial(110720) * math.factorial(76800) 
    * math.factorial(218240) * math.factorial(73600) * math.factorial(72960) 
    * math.factorial(40320) * math.factorial(68480) * math.factorial(74240) 
    * math.factorial(29440) * math.factorial(123520) * math.factorial(76160) 
    * math.factorial(76800) * math.factorial(76160) * math.factorial(28160) 
    * math.factorial(94080) * math.factorial(96640) * math.factorial(124160) 
    * math.factorial(39040) * math.factorial(83200) * math.factorial(46080) 
    * math.factorial(93440) * math.factorial(181760) * math.factorial(70400) 
    * math.factorial(81280) * math.factorial(99200) * math.factorial(77440) 
    * math.factorial(4480) * math.factorial(3840) * math.factorial(9600))) 
+1

這不是一個編程問題。這是一個數學問題。 – ABMagil

+0

這段代碼對我來說看起來像是有效的Python語法。結果有什麼問題嗎? – Kevin

+0

@Kevin:這是有效的語法。結果可能是什麼「錯誤」,可能是OP在放棄等待之前沒有顯示出來。所以ABMagil是正確的,這是一個數學問題。對我而言,這也是一個編程問題,因爲您必須知道如何正確編程數值計算。但要做到這一點,你必須掌握數學和編程知識。 –

回答

1

我不知道你是什麼提出來,但也許

import math 
import operator 

numbers = (1, 103040, 181760, 48000, 119040, 78080, 64000, 163840, 140160, 185600, 
    255360, 131840, 109440, 104960, 144000, 104320, 69120, 96000, 67200, 49280, 
    138240, 103040, 154240, 206080, 49920, 126720, 254720, 83200, 48000, 80640, 142080, 
    124800, 106880, 170880, 128640, 44160, 110720, 76800, 218240, 73600, 72960, 40320, 
    68480, 74240, 29440, 123520, 76160, 76800, 76160, 28160, 94080, 96640, 124160, 39040, 
    83200, 46080, 93440, 181760, 70400, 81280, 99200, 77440, 4480, 3840, 9600) 
print(math.factorial(6400001)/reduce(operator.mul, (math.factorial(i) for i in numbers))) 

可能是你以後......

+3

我想你對你的嘗試有點讚賞(就像@ZeroPiraeus爲了試圖通過使用理智的格式來挽救問題而值得讚賞),但我敢打賭,這不是真正的OP之後。最大的瓶頸是計算6400001的階乘,它不會在合理的時間內完成,並且不會由您的答案解決。 –

0

第一個改進,但仍然太慢:

from collections import Counter 
from heapq import heapify, heappop, heappush, heappushpop 

def fast_mul_many(numbers): 
    heapify(numbers) 

    x = heappop(numbers) 
    while numbers: 
     y = heappop(numbers) 
     x = heappushpop(numbers, x * y) 

    return x 

start = 6400001 

to_divide = [ 
    1,  103040, 181760, 48000, 119040, 
    78080, 64000, 163840, 140160, 185600, 
    255360, 131840, 109440, 104960, 144000, 
    104320, 69120, 96000, 67200, 49280, 
    138240, 103040, 154240, 206080, 49920, 
    126720, 254720, 83200, 48000, 80640, 
    142080, 124800, 106880, 170880, 128640, 
    44160, 110720, 76800, 218240, 73600, 
    72960, 40320, 68480, 74240, 29440, 
    123520, 76160, 76800, 76160, 28160, 
    94080, 96640, 124160, 39040, 83200, 
    46080, 93440, 181760, 70400, 81280, 
    99200, 77440, 4480, 3840, 9600, 
] 

factors = Counter(range(1, start+1)) 

for remove in to_divide: 
    factors.subtract(range(1, remove+1)) 

positives = Counter() + factors 
negatives = Counter() - factors 

fraction_top = fast_mul_many(list(positives.elements())) 
fraction_bottom = fast_mul_many(list(negatives.elements())) 

return fraction_top/fraction_bottom 

這是一個改進。這是至少是您發佈的原始文件的50倍。我猜這是遠遠超過50倍,但它需要一段時間的原始...

from collections import Counter 
from heapq import heapify, heappop, heappush, heappushpop 

def fast_mul_many(numbers): 
    heapify(numbers) 

    x = heappop(numbers) 
    while numbers: 
     y = heappop(numbers) 
     x = heappushpop(numbers, x * y) 

    return x 

start = 6400001 

to_divide = [ 
    1,  103040, 181760, 48000, 119040, 
    78080, 64000, 163840, 140160, 185600, 
    255360, 131840, 109440, 104960, 144000, 
    104320, 69120, 96000, 67200, 49280, 
    138240, 103040, 154240, 206080, 49920, 
    126720, 254720, 83200, 48000, 80640, 
    142080, 124800, 106880, 170880, 128640, 
    44160, 110720, 76800, 218240, 73600, 
    72960, 40320, 68480, 74240, 29440, 
    123520, 76160, 76800, 76160, 28160, 
    94080, 96640, 124160, 39040, 83200, 
    46080, 93440, 181760, 70400, 81280, 
    99200, 77440, 4480, 3840, 9600, 
] 

factors = Counter(range(2, start+1)) 

for remove in to_divide: 
    factors.subtract(range(2, remove+1)) 

max_key = max(factors) 
for key in sorted(factors.keys()): 
    if key > 10000: break 

    if factors[key] == 0: 
     continue 

    for i in range(max_key//key, 1, -1): 
     n = factors.pop(i * key, 0) 
     factors[i] += n 
     factors[key] += n 

positives = Counter() + factors 
negatives = Counter() - factors 

fraction_top = fast_mul_many([x**count for x, count in positives.items()]) 
fraction_bottom = fast_mul_many([x**count for x, count in negatives.items()]) 

fraction_top // fraction_bottom