質問の色玉の確率の問題を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]