# Complexité

import numpy as np

def diviseurs1(n):
    d = 0
    k = 1
    while k <= n:
        if n % k == 0:
            d += 1
        k += 1
    return d


def diviseurs2(n):
    d = 0
    k = 1
    while k * k < n:
        if n % k == 0:
            d += 2
        k += 1
    if k * k == n:
        d += 1
    return d

#Instructions élémentaires
   

"""
Les opérations arithmétiques,
les comparaisons de données élémentaires ()
les transferts de données
les instructions de contrôle
sont considérés de coût constant (1)

En revanche, tester l'égalité de deux chaines de caractère n'est de coût
constant qu'en cas de tests un à un.

Aussi, la recopie d'un tableau n'est pas de coût constant.

Les coûts résonables :
    logarithmique O(log(n))
    linéaire O(n)
    semi-linéaire O(nlog(n))
    quadratique O(n²)
"""

def f1(n):
    x = 0
    for i in range(n):
        for j in range(n):
            x += 1
    return x
#O(n²)

def f2(n):
    pass    


def f4(n): # O(logn)
    x, i = 0, n
    while i > 1:
        x += 1
        i //= 2
    return x


def f5(n): # O(nlog(n))
    x, i = 0, n
    while i > 1:
        for j in range(n):
            x += 1
        i //= 2
    return x

def f6(n):
    x, i = 0, n
    while i > 1:
        for j in range(i) :
            x += 1
        i //= 2
    return x

def cherche(x, l):
    for y in l:
        if y == x:
            return True
    return False

def cherche_dicho(x, l):
    i, j = 0, len(l)
    while i < j:
        k = (i + j) // 2
        if l[k] == x:
            return True
        elif l[k] > x:
            j = k
        else:
            i = k + 1
    return False