eigenmath/choose.cpp

100 lines
1.1 KiB
C++
Raw Permalink Normal View History

2008-05-11 01:16:01 +02:00
// For example, the number of five card hands is choose(52,5)
2008-05-11 01:08:57 +02:00
//
// n!
// choose(n,k) = -------------
// k! (n - k)!
2006-10-13 17:43:11 +02:00
#include "stdafx.h"
#include "defs.h"
void
eval_choose(void)
{
push(cadr(p1));
eval();
push(caddr(p1));
eval();
choose();
}
2008-05-11 00:47:40 +02:00
// Result vanishes for k < 0 or k > n. (A=B, p. 19)
2006-10-13 17:43:11 +02:00
#define N p1
#define K p2
void
2008-05-11 00:32:20 +02:00
choose(void)
2006-10-13 17:43:11 +02:00
{
2008-05-11 00:32:20 +02:00
save();
2006-10-13 17:43:11 +02:00
K = pop();
N = pop();
if (choose_check_args() == 0) {
push_integer(0);
2008-05-11 00:32:20 +02:00
restore();
2006-10-13 17:43:11 +02:00
return;
}
push(N);
factorial();
push(K);
factorial();
divide();
push(N);
push(K);
subtract();
factorial();
divide();
2008-05-11 00:32:20 +02:00
restore();
2006-10-13 17:43:11 +02:00
}
int
choose_check_args(void)
{
if (isnum(N) && lessp(N, zero))
return 0;
else if (isnum(K) && lessp(K, zero))
return 0;
else if (isnum(N) && isnum(K) && lessp(N, K))
return 0;
else
return 1;
}
2007-05-08 16:57:30 +02:00
#if SELFTEST
2006-10-13 17:43:11 +02:00
static char *s[] = {
2008-05-11 01:38:04 +02:00
"choose(52,5)",
"2598960",
2006-10-13 17:43:11 +02:00
"choose(n,k)",
"n!/(k!*(-k+n)!)",
"choose(0,k)",
"1/(k!*(-k)!)",
"choose(n,0)",
"1",
"choose(-1,k)",
"0",
"choose(n,-1)",
"0",
};
void
test_choose(void)
{
test(__FILE__, s, sizeof s / sizeof (char *));
}
2007-05-08 16:57:30 +02:00
#endif