# -*- coding: utf-8 -*-
"""
TP2 : Fonctions - Corrigé

PCSI2 - Albert Schweitzer - Le Raincy
"""

##Q3
import math as m #Pour la racine carré

def est_premier(n:int) -> bool:
    '''
    Renvoie True si n est premier et False sinon
    '''
    for i in range(2, int(m.sqrt(n))+1):
        if n%i == 0: #i divise n !!
            return False
    return True
##Q4
def ValAbs(x:float) -> float:
    '''
    Renvoie la valeur absolue de x
    '''
    if x > 0:
        return x
    else:
        return -x

##Q5
def factorielle(n:int) -> int:
    '''
    Renvoie la valeur de n!
    n est supposé strictement positif
    '''
    fact = 1
    for i in range(1, n+1):
        fact = fact*i
    return fact

##Q6
def somme_inverse(d:int, f: int) -> float:
    '''
    Renvoie la valeur de 1/d+...+1/f
    On suppose 0 < d <= f
    '''
    s = 0
    for i in range(d, f+1):
        s = s + 1/i
    return s

##Q7
def multiples(n:int) -> None:
    '''
    Affiche les multiples de 3 qui ne sont pas
    pairs et qui sont <= n
    '''
    for i in range(3, n+1, 3):
        if i%2 == 1:
            print(i)

##Q8
import random as rd
'''
help(rd.randint) affiche notamment : Return random integer in range [a, b], including both end points.
'''

def somme() -> int:
    s = rd.randint(1, 6) + rd.randint(1, 6)
    return s

def moyenne() -> float:
    '''
    Renvoie la moyenne des sommes de deux lancers
    de dés successifs sur 10000 répétitions
    '''
    s = 0
    for i in range(10000):
        s = s + somme()
    return s/10000

##Q9
def syracuse(n:int, u0:int) -> int:
    '''
    Renvoie la n-ième valeur de la suite de syracuse
    '''
    u = u0
    for i in range(n):
        if u%2 == 0:
            u = u//2
        else:
            u = 3*u + 1
    return u

def temps_vol(u0:int) -> int:
    '''
    Renvoie le temps de vol de la suite de syracuse
    de premier terme u0
    '''
    u = u0
    n = 0
    max = u0
    while u != 1:
        if u%2 == 0:
            u = u//2
        else:
            u = 3*u + 1
        if max < u:#On a trouvé un nouveau maximum
            max = u
        n = n + 1
    return n, max
##Q10
import random as rd
def tirages() -> int:
    '''
    Simule des lancers de pièces et s'arrête quand
    on a 3 piles successifs. Renvoie le nb de
    lancers effectués
    '''
    n = 0 #nb de lancers effectués
    compteur = 0 #nb de piles successifs obtenus
    while compteur < 3:
        piece = rd.randint(0, 1)
        if piece == 1:#On a pile
            compteur = compteur + 1
        else:
            compteur = 0
        n = n + 1
    return n

##Q11
def second(a:float, b:float, c:float) -> int:
    '''
    Renvoie le nb de solutions réelles de aX^2 + bX + c = 0 (-1 pour une infinité)
    '''
    if a == 0:
        if b == 0 and c != 0:
            return 0
        elif b == 0 and c == 0:
            return -1
        else:#Degré 1
            return 1
    delta = b**2 - 4*a*c #discriminant
    if delta < 0:#Pas de sol réelle
        return 0
    if delta == 0:#Une sol réelle
        return 1
    if delta > 0:#Deux sol réelles
        return 2