1 module des.math.combin; 2 3 /// factorial 4 long fact( long a ) pure nothrow 5 in { assert( a >= 0 ); } 6 out(res) { assert( res >= 0 ); } 7 body 8 { 9 if( a <= 2 ) return a; 10 return a * fact(a-1); 11 } 12 13 unittest 14 { 15 assert( fact(0) == 0 ); 16 assert( fact(1) == 1 ); 17 assert( fact(2) == 2 ); 18 assert( fact(3) == 6 ); 19 assert( fact(4) == 24 ); 20 assert( fact(5) == 120 ); 21 } 22 23 /// equals to fact(n) / ( fact(k) * fact( n-k ) ) 24 long combination( long n, long k ) pure nothrow 25 in 26 { 27 assert( k > 0 ); 28 assert( n >= 0 ); 29 } 30 out(res) { assert( res >= 0 ); } 31 body 32 { 33 if( k == 1 || k == n-1 ) return n; 34 long a = n * (n-1); 35 long b = k; 36 37 foreach( i; 2 .. k ) 38 { 39 a *= (n-i); 40 b *= i; 41 } 42 43 return a / b; 44 } 45 46 unittest 47 { 48 static pure nothrow long comb2( long n, long k ) 49 { return fact(n) / ( fact(k) * fact( n-k ) ); } 50 51 foreach( k; 1 .. 10 ) 52 assert( combination(10,k) == comb2(10,k) ); 53 } 54 55 /// equals to fact(n) / fact(n-k) 56 pure nothrow long partial_permutation( long n, long k ) 57 in 58 { 59 assert( k > 0 ); 60 assert( n >= k ); 61 } 62 out(res) { assert( res >= 0 ); } 63 body 64 { 65 if( k == 1 ) return n; 66 67 long res = n * (n-1); 68 69 foreach( i; 2 .. k ) 70 res *= (n-i); 71 72 return res; 73 } 74 75 unittest 76 { 77 static pure nothrow long perm2( long n, long k ) 78 { return fact(n) / fact( n-k ); } 79 80 foreach( k; 1 .. 10 ) 81 assert( partial_permutation(10,k) == perm2(10,k) ); 82 }