問1
1個目のサイコロで今までの目と重複しない確率は 6/6。
2個目のサイコロで今までの目と重複しない確率は 5/6。
3個目のサイコロで今までの目と重複しない確率は 4/6。
全部かければよいので (6×5×4)÷(6×6×6)=5/9≒56%。

問2
分母は (2**128)**1兆。
分子は (2**128)! / (2**128-1兆)!
そのまま計算するのは無理。
wikipedia を見ると、
 n!≒sqrt(2πn)*(n/e)**n
となっているのでこれを利用する。
まずはそのまま double で計算してみるものの、オーバーフローで敗北(指数の爆発)。
仕方ないのでまじめに計算する。
以下の定数を導入する:
 n=2**128
 m=1兆
求める確率pは

p = n! / (n-m)! / n**m
≒ (2πn)**0.5 * (n/e)**n / (2π(n-m))**0.5 * ((n-m)/e)**(n-m) / n**m
= ( n/(n-m))**0.5 * e**-m * (n/(n-m))**(n-m)

ここで、(n/(n-m))**(n-m) を e**m に近似してしまいたくなるが、そうすると誤差が大きすぎて敗北する。
 k=n-m
 s=m/k
を導入する。
p ≒ ( n/k )**0.5 * exp( -m + k*( ln(n/k) ) )
 = ( n/k )**0.5 * exp( -m + k*( ln((k+m)/k) ) )
 = ( n/k )**0.5 * exp( -m + k*( ln(1+s) ) )
s≪1 を利用して、ln( 1+s )をマクローリン展開する。
p ≒ ( n/k )**0.5 * exp( -m * k*(s - s**2/2 + s**3/3))
 = ( n/k )**0.5 * exp( -m + k*s - k*s*s/2 + k*s*s**2/3 )
 = ( n/k )**0.5 * exp( -m*( s/2 - s*s/3 ) )
これでようやく計算することができ、求める確率は
約0.999999999999998560 1-1/700兆
となる。

問3
 n=2**128
 k=n-m
 s=m/k
で、
 p ≒ ( n/k )**0.5 * exp( -m*( s/2 - s*s/3 ) )
が99.9%を下回るmを探す。
二分探索(指数の爆発を利用!)で探すとm=8.25e+17 となる。
一日に10万回なので、225億年となる。宇宙の年齢よりだいぶ長い。

問4
 rubyで書いた。  q4.rb
変更履歴