Skip to content

Commit 055b25c

Browse files
authored
Support const for binomial (#415)
1 parent 1da19a9 commit 055b25c

1 file changed

Lines changed: 24 additions & 11 deletions

File tree

source/mir/combinatorics/package.d

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,45 +85,49 @@ Params:
8585
Returns:
8686
Binomial coefficient
8787
*/
88-
R binomial(R = ulong, T)(T n, T k)
88+
R binomial(R = ulong, T)(const T n, const T k)
8989
if (isArithmetic!(R, T) &&
9090
((is(typeof(T.min < 0)) && is(typeof(T.init & 1))) || !is(typeof(T.min < 0))) )
9191
{
9292
R result = 1;
9393

9494
enum hasMinProperty = is(typeof(T.min < 0));
95+
96+
T n2 = n;
97+
T k2 = k;
98+
9599
// only add negative support if possible
96100
static if ((hasMinProperty && T.min < 0) || !hasMinProperty)
97101
{
98-
if (n < 0)
102+
if (n2 < 0)
99103
{
100-
if (k >= 0)
104+
if (k2 >= 0)
101105
{
102-
return (k & 1 ? -1 : 1) * binomial!(R, T)(-n + k-1, k);
106+
return (k2 & 1 ? -1 : 1) * binomial!(R, T)(-n2 + k2 - 1, k2);
103107
}
104-
else if (k <= n)
108+
else if (k2 <= n2)
105109
{
106-
return ((n-k) & 1 ? -1 : 1) * binomial!(R, T)(-k-1, n-k);
110+
return ((n2 - k2) & 1 ? -1 : 1) * binomial!(R, T)(-k2 - 1, n2 - k2);
107111
}
108112
}
109-
if (k < 0)
113+
if (k2 < 0)
110114
{
111115
result = 0;
112116
return result;
113117
}
114118
}
115119

116-
if (k > n)
120+
if (k2 > n2)
117121
{
118122
result = 0;
119123
return result;
120124
}
121-
if (k > n - k)
125+
if (k2 > n2 - k2)
122126
{
123-
k = n - k;
127+
k2 = n2 - k2;
124128
}
125129
// make a copy of n (could be a custom type)
126-
for (T i = 1, m = n; i <= k; i++, m--)
130+
for (T i = 1, m = n2; i <= k2; i++, m--)
127131
{
128132
// check whether an overflow can happen
129133
// hasMember!(Result, "max") doesn't work with dmd2.068 and ldc 0.17
@@ -189,6 +193,15 @@ version(mir_test) unittest
189193
assert(binomial!BigInt(-5, -7) == 15);
190194
}
191195

196+
version(mir_test)
197+
@safe pure nothrow @nogc
198+
unittest
199+
{
200+
const size_t n = 5;
201+
const size_t k = 2;
202+
assert(binomial(n, k) == 10);
203+
}
204+
192205
/**
193206
Creates a projection of a generalized `Collection` range for the numeric case
194207
case starting from `0` onto a custom `range` of any type.

0 commit comments

Comments
 (0)