質問の色玉の確率の問題をJavaで解いてみた。

 質問の色玉の確率の問題Javaで解いてみました。(^_^;
 色玉に次のように0〜19までの通し番号を与えると、その通し番号を10で割った整数の商が色を、10で割った余りに1を加えた数が元の1から10までの番号を表します。

         1, 2, 3, 4, 5, 6, 7, 8, 9,10
白球(0)  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
赤球(1) 10,11,12,13,14,15,16,17,18,19

 配列pに通し番号を入れて順列を生成させて、次の(1),(2)の条件を満たす場合をそれぞれカウントします。
(1)4つ目を取り出したときに初めて同じ番号の対が出来るのは、
 {1番目}≠{2番目} and {1番目}≠{3番目} and {2番目}≠{3番目}…①
 {1番目}={4番目} or {2番目}={4番目} or {3番目}={4番目}…②
とすると、① and ②ですが、ネストを深くしたくないので、①で、continueを使うために、ド・モルガンの法則を使って、次の③のように変形しました。
 {1番目}={2番目} or {1番目}={3番目} or {2番目}={3番目}…③
(2)2つ目の番号よりも4つ目の番号の方が大きくなるのは、次のときです。
 p[2-1]%10+1< p[4-1]%10+1
∴p[1]%10< p[3]%10

※参考URL
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1335557553

● ProBall3.java

/* 
 * ProBall3.java
 * 
 */

public class ProBall3 {
    // 順列生成
    static boolean nextPerm(int[] p, int n, int r) {
        int i, j;
        int t;
        
        if(r <= 0 || n < r) return(false);
        for(i = r + 1; i <= n-1; i++)
            for(j = i; j >= r + 1 && p[j-1] < p[j]; j--){
                t = p[j]; p[j] = p[j-1]; p[j-1] = t;    // swap(p,j,j-1);
            }
        for(i = n - 1; i > 0 && p[i-1] >= p[i]; i--);
        if(i==0) return(false);
        for(j = n - 1; j > i && p[i-1] >= p[j]; j--);
        t = p[j]; p[j] = p[i-1]; p[i-1] = t;            // swap(p,j,i-1);
        for(j = n - 1; i < j; i++, j--){
            t = p[i]; p[i] = p[j]; p[j] = t;            // swap(p,i,j);
        }
        return(true);
    }
    
    static int gcd(int a, int b){
        return( b == 0 ? a : gcd(b, a % b) );
    }
    
    public static void main(String[] args) {
        final int N = 20, R = 4;
        int[] p = {
             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
            10,11,12,13,14,15,16,17,18,19
        };
        int iTotal=0, iCount1=0, iCount2=0, g=1;
        
        long tm=System.nanoTime();      // Timer Start
        do{
            iTotal++;
            if(p[1]%10< p[3]%10) iCount2++;
            if(p[0]%10==p[1]%10 || p[0]%10==p[2]%10 || p[1]%10==p[2]%10) continue;
            if(p[0]%10==p[3]%10 || p[1]%10==p[3]%10 || p[2]%10==p[3]%10) iCount1++;
        }while(nextPerm(p,N,R));
        if(iCount1!=0) g=gcd(iCount1, iTotal);
        System.out.printf("(1)%3d / %d = %d / %d\n",iCount1,iTotal,iCount1/g,iTotal/g);
        if(iCount2!=0) g=gcd(iCount2, iTotal);
        System.out.printf("(2)%3d / %d = %d / %d\n",iCount2,iTotal,iCount2/g,iTotal/g);
        tm=System.nanoTime()-tm;        // Timer Stop
        System.out.printf("Runtime : %.3f [sec]\n",(double)tm/1e9);
    }
}

●実行結果

(1)17280 / 116280 = 48 / 323
(2)55080 / 116280 = 9 / 19
Runtime : 0.116 [sec]