source code

/**
* Robert Sedgewick Algorithms in C++<br>
* Chapter 35 Random Numbers<br>
* Problem5<br>
* ランダムな2次元のイメージを生成するプログラムを書け。例えば、ビットをランダムに発生し、1なら"*"、0なら" "を出力する。あるいは、2次元デカルト座標系の座標として乱数を用い、その点に"*"を書く。
*/
public class Chapter35RandomNumbersProblem5 {
public static void main(String[] args) {
Chapter35RandomNumbersProblem5 o = new Chapter35RandomNumbersProblem5();
o.run();
}

private void run() {
LinearCongruentialMethod rng = new LinearCongruentialMethod((int) System.nanoTime());
StringBuilder sb = new StringBuilder();
for (int r = 0; r < 100; r++) {
for (int c = 0; c < 100; c++) {
sb.append(rng.nextInt(2) == 0 ? " " : "*");
}
sb.append("\n");
}
System.out.format("%s\n", sb.toString());
}

private class LinearCongruentialMethod {
private int a = 1234567;
private int b = 31415821;
// private int b = 101011;
private int m = 100000000;
private int m2 = 10000;

public LinearCongruentialMethod(int seed) {
a = seed;
}

public int nextInt() {
a = (mult(a, b) + 1) % m;
return a;
}

public int nextIntBad(int r) {
a = (mult(a, b) + 1) % m;
return a % r;
}

public int nextInt(int r) {
a = (mult(a, b) + 1) % m;
return ((a / m2) * r) / m2;
}

private int mult(int a, int b) {
int a1 = a / m2;
int a2 = a % m2;
int b1 = b / m2;
int b2 = b % m2;
if (a * b != (a1 * m2 + a2) * (b1 * m2 + b2)) {
throw new AssertionError();
}
if ((a1 * m2 + a2) * (b1 * m2 + b2) != (a1 * b1) * m + (a2 * b1 + a1 * b2) * m2 + (a2 * b2)) {
throw new AssertionError();
}
return (((a2 * b1 + a1 * b2) % m2) * m2 + (a2 * b2)) % m;
}
}

}