# Python 3.9
import random
import math
import time
twopi = 2.0*math.pi
def trial():
"""
place a point at (1,0) and four other points randomly on the unit circle
return boolean a**2<b*c; a = area of petal touching point A, b = etc.
"""
theta = [0.] + sorted([twopi*random.random() for _ in range(4)])
A,B,C,D,E = [(math.cos(theta[i]), math.sin(theta[i])) for i in range(5)]
return area(A,B,C,D,E)**2 < area(B,C,D,E,A) * area(C,D,E,A,B) # a**2<bc
#return area(A,B,C,D,E)**2 < area(C,D,E,A,B) * area(D,E,A,B,C) # a**2<cd
def area(A,B,C,D,E):
"""
return the area of triangle APQ (the petal touching A) where A,B,C,D,E
are points on the perimeter of the circle, in *counterclockwise* order
"""
P = intersection(A,C,B,E)
Q = intersection(A,D,B,E)
return 0.5 * ( A[0]*(P[1]-Q[1]) + P[0]*(Q[1]-A[1]) + Q[0]*(A[1]-P[1]) )
def intersection(P,Q,R,S):
"""
return the point of intersection of line(P,Q) and line(R,S)
each line is specified by a pair of points, e.g. P=(x,y) in rect. coords.
"""
t = ( (S[0]-R[0])*(R[1]-P[1]) - (S[1]-R[1])*(R[0]-P[0]) ) / \
( (S[0]-R[0])*(Q[1]-P[1]) - (S[1]-R[1])*(Q[0]-P[0]) )
return (P[0] + t*(Q[0]-P[0]), P[1] + t*(Q[1]-P[1]))
nsamp = 10**5 #<--------- sample-size
print(f"{nsamp=}")
start = time.time()
nsucc = sum(trial() for _ in range(nsamp))
print(f"{nsucc=}")
phat = nsucc / nsamp
print(f"{phat=:.6f}")
sdev = math.sqrt(phat*(1-phat)/nsamp)
print(f"99.9% CI for p: {phat:.6f} +- {3.29053*sdev:.6f} \
= ({phat-3.29053*sdev:.6f}, {phat+3.29053*sdev:.6f})")
tsecs = time.time() - start
print(f"time elapsed \
= ({tsecs:9.2f} s) = ({tsecs/60:7.2f} m) = ({tsecs/3600:5.2f} h)")
IyBQeXRob24gMy45CgppbXBvcnQgcmFuZG9tCmltcG9ydCBtYXRoIAppbXBvcnQgdGltZQoKdHdvcGkgPSAyLjAqbWF0aC5waQoKZGVmIHRyaWFsKCk6CiAgICAiIiIKICAgIHBsYWNlIGEgcG9pbnQgYXQgKDEsMCkgYW5kIGZvdXIgb3RoZXIgcG9pbnRzIHJhbmRvbWx5IG9uIHRoZSB1bml0IGNpcmNsZQogICAgcmV0dXJuIGJvb2xlYW4gYSoqMjxiKmM7IGEgPSBhcmVhIG9mIHBldGFsIHRvdWNoaW5nIHBvaW50IEEsIGIgPSBldGMuCiAgICAiIiIKICAgIHRoZXRhID0gWzAuXSArIHNvcnRlZChbdHdvcGkqcmFuZG9tLnJhbmRvbSgpIGZvciBfIGluIHJhbmdlKDQpXSkKICAgIEEsQixDLEQsRSA9IFsobWF0aC5jb3ModGhldGFbaV0pLCBtYXRoLnNpbih0aGV0YVtpXSkpIGZvciBpIGluIHJhbmdlKDUpXQogICAgcmV0dXJuIGFyZWEoQSxCLEMsRCxFKSoqMiA8IGFyZWEoQixDLEQsRSxBKSAqIGFyZWEoQyxELEUsQSxCKSAjIGEqKjI8YmMKICAgICNyZXR1cm4gYXJlYShBLEIsQyxELEUpKioyIDwgYXJlYShDLEQsRSxBLEIpICogYXJlYShELEUsQSxCLEMpICMgYSoqMjxjZAoKZGVmIGFyZWEoQSxCLEMsRCxFKToKICAgICIiIgogICAgcmV0dXJuIHRoZSBhcmVhIG9mIHRyaWFuZ2xlIEFQUSAodGhlIHBldGFsIHRvdWNoaW5nIEEpIHdoZXJlIEEsQixDLEQsRSAgCiAgICBhcmUgcG9pbnRzIG9uIHRoZSBwZXJpbWV0ZXIgb2YgdGhlIGNpcmNsZSwgaW4gKmNvdW50ZXJjbG9ja3dpc2UqIG9yZGVyCiAgICAiIiIKICAgIFAgPSBpbnRlcnNlY3Rpb24oQSxDLEIsRSkKICAgIFEgPSBpbnRlcnNlY3Rpb24oQSxELEIsRSkKICAgIHJldHVybiAwLjUgKiAoIEFbMF0qKFBbMV0tUVsxXSkgKyBQWzBdKihRWzFdLUFbMV0pICsgUVswXSooQVsxXS1QWzFdKSApCgpkZWYgaW50ZXJzZWN0aW9uKFAsUSxSLFMpOgogICAgIiIiCiAgICByZXR1cm4gdGhlIHBvaW50IG9mIGludGVyc2VjdGlvbiBvZiBsaW5lKFAsUSkgYW5kIGxpbmUoUixTKQogICAgZWFjaCBsaW5lIGlzIHNwZWNpZmllZCBieSBhIHBhaXIgb2YgcG9pbnRzLCBlLmcuIFA9KHgseSkgaW4gcmVjdC4gY29vcmRzLgogICAgIiIiCiAgICB0ID0gKCAoU1swXS1SWzBdKSooUlsxXS1QWzFdKSAtIChTWzFdLVJbMV0pKihSWzBdLVBbMF0pICkgLyBcCiAgICAgICAgKCAoU1swXS1SWzBdKSooUVsxXS1QWzFdKSAtIChTWzFdLVJbMV0pKihRWzBdLVBbMF0pICkKICAgIHJldHVybiAoUFswXSArIHQqKFFbMF0tUFswXSksIFBbMV0gKyB0KihRWzFdLVBbMV0pKQoKbnNhbXAgPSAxMCoqNSAgICAjPC0tLS0tLS0tLSBzYW1wbGUtc2l6ZQpwcmludChmIntuc2FtcD19IikKCnN0YXJ0ID0gdGltZS50aW1lKCkgCgpuc3VjYyA9IHN1bSh0cmlhbCgpIGZvciBfIGluIHJhbmdlKG5zYW1wKSkgCnByaW50KGYie25zdWNjPX0iKQoKcGhhdCA9IG5zdWNjIC8gbnNhbXAgCnByaW50KGYie3BoYXQ9Oi42Zn0iKQoKc2RldiA9IG1hdGguc3FydChwaGF0KigxLXBoYXQpL25zYW1wKSAKcHJpbnQoZiI5OS45JSBDSSBmb3IgcDoge3BoYXQ6LjZmfSArLSB7My4yOTA1MypzZGV2Oi42Zn0gXAo9ICAoe3BoYXQtMy4yOTA1MypzZGV2Oi42Zn0sIHtwaGF0KzMuMjkwNTMqc2RldjouNmZ9KSIpCgp0c2VjcyA9IHRpbWUudGltZSgpIC0gc3RhcnQKcHJpbnQoZiJ0aW1lIGVsYXBzZWQgXAo9ICh7dHNlY3M6OS4yZn0gcykgPSAoe3RzZWNzLzYwOjcuMmZ9IG0pID0gKHt0c2Vjcy8zNjAwOjUuMmZ9IGgpIik=