Mathematics.java

View source code here on GitHub!

public class Mathematics
public static long factorial(long n)
Returns:

The factorial of a given number

public static long nChooseR(long n, long r)
Returns:

The number of ways to choose r items from a collection of size n.

 1package euler.lib;
 2
 3public class Mathematics {
 4    public static long factorial(long n) {
 5        long answer = 1;
 6        for (long x = 2; x <= n; x += 1)
 7            answer *= x;
 8        return answer;
 9    }
10
11    public static long nChooseR(long n, long r) {
12        if (n <= 20)
13            return factorial(n) / factorial(r) / factorial(n - r);
14        long answer, tmp;
15        int i, j;
16        byte[] factors = new byte[(int) (n + 1)];
17        // collect factors of final number
18        for (i = 2; i <= n; i += 1)
19            factors[i] = 1;
20
21        // negative factor values indicate need to divide
22        for (i = 2; i <= r; i += 1)
23            factors[i] -= 1;
24        for (i = 2; i <= n - r; i += 1)
25            factors[i] -= 1;
26
27        // this loop reduces to prime factors only
28        for (i = (int) n; i > 1; i -= 1) {
29            for (j = 2; j < i; j += 1) {
30                if (i % j == 0) {
31                    factors[j] += factors[i];
32                    factors[i / j] += factors[i];
33                    factors[i] = 0;
34                    break;
35                }
36            }
37        }
38
39        i = j = 2;
40        answer = 1;
41        while (i <= n) {
42            while (factors[i] > 0) {
43                tmp = answer;
44                answer *= i;
45                while (answer < tmp && j <= n) {
46                    while (factors[j] < 0) {
47                        tmp /= j;
48                        factors[j] += (byte) 1;
49                    }
50                    j += 1;
51                    answer = tmp * i;
52                }
53                if (answer < tmp)
54                    return -1; // this indicates an overflow
55                factors[i] -= 1;
56            }
57            i += 1;
58        }
59
60        while (j <= n) {
61            while (factors[j] < 0) {
62                answer /= j;
63                factors[j] += (byte) 1;
64            }
65            j += 1;
66        }
67
68        return answer;
69    }
70}