在Obj-C中生成大数组合

时间:2012-11-06 08:55:33

标签: objective-c combinatorics

tl; dr :如何在Objective-C中处理20! * 20!等数字?


我正在通过Project Euler学习Objective-C。这很有趣,但我遇到的一个问题是使用任意大数字。我对这些事情仍然非常环保,所以我不知道为什么类似Python的东西比Obj-C更容易处理大数字。

Problem 15

为例
  

Starting in the top left corner of a 2 x 2 grid, there are 6 routes (without backtracking) to the bottom right corner.

     

How many routes are there through a 20 x 20 grid?

这很容易。使用组合学:

  

(20 + 20)! / 20!(20!)
   - > 815915283247897734345611269596115894272000000000/5919012181389927685417441689600000000
   - > 137846528820

在Python中:

import math  
print math.factorial(40) / (math.factorial(20) * math.factorial(20))

在Objective-C中,但是?我还没有办法强制通过这么大的数字。使用2 x 2示例工作正常。我应该得到9C4 = 126。但是我应该如何处理像20!这样的数字?

我已经尝试使用NSDecimalNumber,它似乎支持每个数字更多的数字,假设您可以将其转换为Mantissa x Exponent并且不介意精度损失,但这并不是'事实证明它太有用了,因为我无法弄清楚如何让Obj-C从%llu创建一个尾数,并且我精神损失。

到目前为止,我所使用的代码正确生成了阶乘,因为它显示unsigned long long处理的值太大,但在x * y上窒息,因此getCombinatoricOf:20 and:20返回1

#import "Problem15.h"

@implementation Problem15

- (unsigned long long)factorial:(NSNumber *)number {
    unsigned long long temp = 1;
    for (int i = [number intValue]; i > 0; i--) {
        temp *= i;
    }
    return temp;
}

- (unsigned long long)getCombinatorcOf:(NSNumber *)x and:(NSNumber *)y {
    NSNumber *n = @([x intValue] + [y intValue]);
    NSNumber *n_factorial = @([self factorial:n]);
    NSNumber *x_factorial = @([self factorial:x]);
    NSNumber *y_factorial = @([self factorial:y]);
    return ([n_factorial unsignedLongLongValue] / ([x_factorial unsignedLongLongValue] * [y_factorial unsignedLongLongValue]));
}

- (NSString *)answer {
    NSNumber *x = @5;
    NSNumber *y = @4;
    unsigned long long answer = [self getCombinatoricOf:x and:y];
    return [NSString stringWithFormat:@"\n\nProblem 15: \nHow many routes are there through a 20 x 20 grid? \n%llu", answer];
}

@end

1 个答案:

答案 0 :(得分:1)

这不是Objective-C,但你可以像普通的C库一样使用GMP

还有GMP的Objective-C包装器,如GMPInt