Brute force gives me about 2287/2288. Trying each number 1,000,000 times (distribute X balls in 365 bins, count number times all bins are filled) so it seems reliable, but maybe I have bug somewhere:
import java.util.Random;
public class Birthday {
private static Random rand = new Random(System.currentTimeMillis());
public static void main(String... args) {
final int n = 365;
boolean[] bins = new boolean[n];
final float maxNumberOfAttempts = 1000000;
for (int numberOfBalls = 2285; numberOfBalls <= 2400; ++numberOfBalls) {
int attempts = 0;
int numberOfTimesAllBinsFilled = 0;
while (attempts < maxNumberOfAttempts) {
if (distribute_X_Balls_in_N_bins_randomly_and_return_the_number_of_filled_bins(
numberOfBalls, bins) == n) {
numberOfTimesAllBinsFilled++;
}
++attempts;
}
float prob = numberOfTimesAllBinsFilled / maxNumberOfAttempts;
System.out.println((prob > .5 ? "PASSED:" : "FAILED:") + numberOfBalls + ":" + prob);
}
}
public static int distribute_X_Balls_in_N_bins_randomly_and_return_the_number_of_filled_bins(
int x, boolean[] bins) {
for (int inx = 0; inx < bins.length; ++inx) {
bins[inx] = false;
}
int whichBin = 0;
int total = 0;
while (--x >= 0) {
whichBin = rand.nextInt(bins.length);
if (!bins[whichBin]) {
bins[whichBin] = true;
++total;
if (total == bins.length) {
return total;
}
}
}
return total;
}
}