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 sizen
.
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}