The probability that two people have the same birthday in a room full of n people is 1-p. Where:
p = 365! / 365^n(365 - n)!
Obviously the numbers will be too big to solve this equation, what is a creative way to go about this?
I already solved this in a different way using simulation, but I figured the formula might be more elegant.
Holly Macaroni! What a show!
Anyway, right way to compute such things with large intermediates is to log() them
p = exp(log(p))
log(p) = log(365!) - n*log(365) - log((365 - n)!)
For factorial, use Gamma function, G(n+1)=n!, and there is very handy function in C library which computes log(G(x)): lgamma(x)
No more loops, no long doubles, no bignum libraries, no overflows...
Code
#include <math.h>
#include <stdio.h>
double b(int n) {
double l = lgamma(365.0 + 1.0) -
(double)n * log(365.0) -
lgamma(365.0 - (double)n + 1.0);
return exp(l);
}
int main() {
double p = b(20);
printf("%e %e\n", p, 1.0 - p);
return 0;
}
You can take advantage of 365!/(365-n)! = 365 * 364 * ... * (365-(n-1))
So to calculate this term ( let it be A=365!/(365-n)! ) you can simply the above numbers like this:
unsinged double A=1; // to make sure there is no overflow
for(int i=0;i<n;i++) A*=365-i;
To take it one step further : p=A/365^n = (364*363*...*(365-(n-1)))/365^(n-1)= 364/365 * 363/365 * ... (365-(n-1))/365.
so p can be calcuated like this:
unsigned double p=1;
for(int i=0;i<n;i++) p*= (365-i)/365.0;
in linear time
I think this should work :P
You don't want to calculate the full factorial. Instead, calculate each term and multiply to the result.
The probability you don't share a birthday with:
Given this, you calcuate p
as follows.
int n = 30;
int i;
double p = 1;
for (i = 1; i < n; i++) {
p *= (365 - i) / 365.0;
printf("i=%d, p=%f\n", i, 1-p);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With