/**
* Robert Sedgewick Algorithms in C++<br>
* Chapter 35 Random Numbers<br>
* Problem9<br>
* 常に同じ値を返すような縮退した乱数発生器の場合、χ2乗の値はいくらか?
*/
public class Chapter35RandomNumbersProblem9 {
public static void main(String[] args) {
Chapter35RandomNumbersProblem9 o = new Chapter35RandomNumbersProblem9();
o.run();
}

private void run() {
Random rng = new Random();
int N = 1 + (int) (999 * rng.nextDouble());
int r = 1 + (int) (999 * rng.nextDouble());
int[] a = new int[N];
double chisquare = chisquare(a, r);
double chisquare2 = N * N / ((double) N / r) - N;
double chisquare3 = (double) N * (r - 1);
boolean b = Math.abs(chisquare - chisquare2) < 1e-5;
boolean c = Math.abs(chisquare2 - chisquare3) < 1e-5;
if (!(b && c)) {
debug(N, r);
throw new AssertionError();
}
System.out.format("chisquare\n = N * (r - 1)\n = %d * (%d - 1)\n = %10.5f\n", N, r, chisquare3);
}

private double chisquare(int[] a, int r) {
int N = a.length;
int[] count = new int[r];
for (int i = 0; i < N; i++) {
count[a[i]]++;
}
double t = 0;
for (int i = 0; i < count.length; i++) {
t += count[i] * count[i];
}
return t / ((double) N / r) - N;
}

private static final boolean DEBUG = true;

private static final void debug(Object... o) {
if (DEBUG)
System.err.println(Arrays.deepToString(o));
}

private static final void message(Object... o) {
System.err.println(Arrays.deepToString(o));
}

}