2014-06-12 98 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