# simulation de Bernoulli, d'une loi binimale comme somme de Bernoulli
from random import *
from math import *
#from time import *

from matplotlib.pyplot import *
from numpy import linspace

#################################################################
# 1) a) b) c)  CONVERSION DECONVERSION

def conv(n):
    if n<=1:
        return(str(n))
    else:
        return(conv(n//2)+str(n%2))

def deconv(S):
    p=len(S)
    return sum(int(S[i])*2**(p-1-i) for i in range(p) )

def toto(n):
    return(n-deconv(conv(n)))

def titi(N):
    for n in range(N):
        if toto(n)!=0:
            return False
    return True


###########################################################
# SEGMENT -  SEGMENT -  SEGMENT -  SEGMENT -  SEGMENT - 
def segment(n):
    if n==0:
        return [0,1]
    else:
        S=segment(n-1)
        if n%3==0:
            return [S[0],(S[0]+S[1])/2]
        else:
            return [(S[0]+S[1])/2,S[1]]

for n in range(2):
    print(n,'  ',segment(n))

###############################################
#3.    
def v(n):
    c=0
    while n%2==0:
        c=c+1
        n=n//2
    return c

def s(n):
    if n<2:
        return n
    else:
        return s(n//2)+n%2



def prod(m,n):
    return [v(m*n),v(m),v(n),v(m*n)-(v(m)+v(n))]

def verif():
    for n in range(2,10001):
        if v(n)-s(n-1)+s(n)-1!=0:
            return 'faux'
    return 'vrai'

################################################
# LOIS USUELLES - LOIS USUELLES - LOIS USUELLES - LOIS USUELLES -
def u(): # simule un nombre réel entre 0 et 1
    return(random())
   
def F_u(x,nb): # Que fait cette fonction?
    c=0
    for j in range(nb):
        tirage=u()
        if tirage<=x:
            c=c+1
    return c/nb
        

def trace_u(nb): # Que fait cette fonction?
    LX=linspace(-1,2,500)
    print(len(LX))
    LY=[F_u(p,nb) for p in LX]
    plot(LX,LY)
    show()


# Q_3 #########################################☺
def  ber(p):   #tirage de Bernoulli  b(p)=B(p)
    tirage=random()
    if tirage<p:
        return 1
    else:
        return 0

# Q_4 #########################################☺


def  bino(n,p): # S simule la somme de n épreuve de Bernoulli B(p)
    somme=0
    for i in range(n):
        somme=somme+ber(p)
    return somme

def binoT(k,n,p):  #binomiale théorique bino(n,p)=B(n,p)
    return factorial(n)/factorial(k)/factorial(n-k)*p**k*(1-p)**(n-k)


### Vérifiaction expérimentale(début)
def listebinoT(n,p): # liste théorique des probabilités de B(n,p)
    c=(n+1)*[0]
    for k in range(n+1):
        c[k]=binoT(k,n,p)
    return c


def Verification(n,p,nb): # on simule nb tirage de S puis on compte le nb de fois 
                       # où S=k et on renvoie la liste des différences entre 
                       # les proba simulées et théoriques : P(S=k),k=0..n                          
    L=nb*[0]
    for i in range(nb):
        L[i]=bino(n,p)
    c=(n+1)*[0]
    for i in range(nb):
        for k in range(n+1):
            if L[i]==k:
                c[k]=c[k]+1
    for k in range(n+1):
        c[k]=c[k]/nb
    cc=listebinoT(n,p) 
    return [c[i]-cc[i] for i in range(n+1)] 

### Vérifiaction expérimentale(fin)
   
   
# Q_5 #########################################☺
   
def geo(p):
    tirage=random()
    essai=1
    while tirage>=p:
        tirage=u()
        essai+=1
    return essai
   


# Q_6 #########################################☺   
def geoS(p,k,nb):
    s=0
    for n in range(nb):
        tirage=geo(p)
        if tirage==k:
            s=s+1
    return [s/nb,p*(1-p)**(k-1)]

# Q_7  #########################################☺
def espS(p,nb):
    s=0
    for n in range(nb):
        s=s+geo(p)
    return s/nb

def esp2(p,nb): # espérance de X^2
    s=0
    for n in range(nb):
        s=s+geo(p)**2
    return s/nb
  
def V(p,nb):
    return [esp2(p,nb)-espS(p,nb)**2,(1-p)/p**2]
    
# VIGNETTE - VIGNETTE - VIGNETTE - VIGNETTE - 
# Q_8 #########################################☺
def collec():
    nbt=0 # nombre de tablettes
    nbj=0 # nombre d'images de joueurs
    C=15*[0] # tableau des images
    while nbj<15:    
        nbt+=1 # une tablette de plus achetée
        aux=randint(0,14)
        if C[aux]==0:
            nbj+=1 # un joueur de plus dans la collec
            C[aux]=1 # on colle l'image dans son tableau
        
    return(nbt) # retourne le nb de tablette achetées pour avoir les 15 images

def parent(nb): # espérance simulée
    s=0
    for i in range(nb):
        s=s+collec()
    return(s/nb)
        
#Q_9################################
def espVignetteTheorique(): # espèrance théorique 
    s=0.
    for i in range(1,16):
        s=s+1/i
    return(15*s) # 

def esp2Vignette(nb): # espérance de X^2 simulée 
    s=0
    for i in range(nb):
        s=s+collec()**2
    return(s/nb)
   

def var(nb): # variance simulée 
    return(esp2Vignette(nb)-parent(nb)**2)

def varTheorique(): # variance  théorique
    s=0.
    for i in range(1,16):
        p=(15-i+1)/15
        q=1-p
        s=s+q/p**2
    return(s) 



# EHRENFEST - EHRENFEST - EHRENFEST - EHRENFEST - 
# Q_10...Q_13 #########################################☺
def X(n,b):
    u1=0
    u2=b
    for i in range(n):
        if u1==0:
            u1=1
            u2=b-1
        elif u2==0:
            u1=b-1
            u2=1
        else:
            tir=randint(1,b)
            if tir<=u1:
                u1=u1-1
                u2=u2+1
            else:
                u1=u1+1
                u2=u2-1
        #print([u1,u2])
    return u1
          
def EX(n,b,nb):
    s=0
    for i in range(nb):
        s=s+X(n,b)
    return [s/nb,(b/2)*(1-(1-2/b)**n)]

def retour(b):
    u1=1
    u2=b-1
    n=1
    while u1!=0:
        n=n+1
        if u2==0:
            u1=b-1
            u2=1
        else:
            tir=randint(1,b)
            if tir<=u1:
                u1=u1-1
                u2=u2+1
            else:
                u1=u1+1
                u2=u2-1
        #print([u1,u2])
    return n 

def ER(b,nb):
    s=0
    for i in range(nb):
        s=s+retour(b)
    return [s/nb,2**b]


# MOUVEMENT BROWNIEN -MOUVEMENT BROWNIEN -MOUVEMENT BROWNIEN -
#Q_14 et Q_15 ##############################################################
def N(): # nb de pas pour sortir du disque
    n=0
    d2=0
    x=0
    y=0
    while d2<40000:
        n=n+1
        t=2*pi*randint(0,359)/360
        aux=x
        x=x+10*cos(t)
        y=y+10*sin(t)
        d2=x**2+y**2
        #print([x,y])
    return n

for mb in range(1000):
    a=N()
    if a<50:
        print(a,end=' ')
    
def E(nb):
    s=0
    for i in range(nb):
        s=s+N()
    return s/nb
