import random  # 乱数を扱うためのモジュールをインポート
import math  # 数学関係の機能をまとめたモジュールをインポート
n = 100000  # 試行回数
a = 100
b = 30
random.seed(1)  # 乱数のシード値を固定
x = [random.uniform(0,a) for _ in range(n)]  # U(0,a)に従う乱数をn個生成
y = [random.uniform(0,a) for _ in range(n)]  # U(0,a)に従う乱数をn個生成
u = [min(xi,yi) for xi,yi in zip(x,y)]
v = [max(xi,yi) for xi,yi in zip(x,y)]
z = [random.uniform(xi, a) for xi in x]  # U(x,a)に従う乱数をn個生成
# (1) 確率を表示 (※モンテカルロ法で求めた値，理論値の順)
print(sum(abs(xi-yi)<=b for xi,yi in zip(x,y))/n)
print(1-((a-b)**2)/(a**2))
# (2) 確率を表示 (※モンテカルロ法で求めた値，理論値の順)
print(sum(ui<a/2 and vi<ui+a/2 and a/2<vi for ui,vi in zip(u,v))/n)
print(1/4)
# (3) 確率を表示 (※モンテカルロ法で求めた値，理論値の順)
print(sum(xi>b and a-zi>b for xi,zi in zip(x,z))/n)
print((a-2*b)/a + (b/a)*math.log(b/(a-b)))