web-dev-qa-db-fra.com

fonction isPrime pour le langage Python

J'ai donc pu résoudre ce problème avec un peu d'aide d'Internet et voici ce que j'ai obtenu:

def isPrime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False

    return True

Mais ma question est vraiment comment le faire, mais POURQUOI. Je comprends que 1 n’est pas considéré comme un nombre premier bien qu’il le soit, et si il se divise par RIEN dans la plage, il est automatiquement premier et renvoie la déclaration False. mais ma question est quel rôle joue la quadrature du "n" ici? Merci beaucoup pour votre attention

P.s. Je suis très inexpérimenté et je viens d’être initié à la programmation il ya un mois: S

Parmi les nombreux tests de primalité flottant sur Internet, considérons le test principal suivant:

def is_prime(n):
  if n == 2 or n == 3: return True
  if n < 2 or n%2 == 0: return False
  if n < 9: return True
  if n%3 == 0: return False
  r = int(n**0.5)
  f = 5
  while f <= r:
    print '\t',f
    if n%f == 0: return False
    if n%(f+2) == 0: return False
    f +=6
  return True    

Considérons le nombre premier 5003:

print is_prime(5003)

Impressions:

 5
 11
 17
 23
 29
 35
 41
 47
 53
 59
 65
True

La ligne r = int(n**0.5) est évaluée à 70 (la racine carrée de 5003 est 70.7318881411 et int() tronque cette valeur)

En raison des premiers tests et des tests en milieu de boucle, il suffit d'évaluer la boucle tous les 6 chiffres. 

Considérez le prochain nombre impair (puisque tous les nombres pairs autres que 2 ne sont pas des nombres premiers) de 5005, la même chose est imprimée:

 5
False

La limite est la racine carrée depuis x*y == y*x. La fonction n'a qu'à parcourir 1 boucle pour trouver que 5005 est divisible par 5 et donc non premier. Depuis 5 X 1001 == 1001 X 5 (et les deux sont 5005), nous n'avons pas besoin d'aller jusqu'au 1001 dans la boucle pour savoir ce que nous savons à 5!


Maintenant, regardons l'algorithme que vous avez:

def isPrime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False

    return True

Il y a deux problèmes:

  1. Il ne vérifie pas si n est inférieur à 2 et s'il n'y a pas de nombre premier inférieur à 2;
  2. Il teste chaque nombre compris entre 2 et n ** 0.5, y compris tous les nombres pairs et impairs. Puisque tout nombre supérieur à 2 divisible par 2 n'est pas un nombre premier, nous pouvons l'accélérer un peu en ne testant que les nombres impairs supérieurs à 2.

Alors: 

def isPrime2(n):
    if n==2 or n==3: return True
    if n%2==0 or n<2: return False
    for i in range(3,int(n**0.5)+1,2):   # only odd numbers
        if n%i==0:
            return False    

    return True

OK - cela accélère d'environ 30% (je l'ai mesuré ...)

L’algorithme que j’ai utilisé is_prime est environ deux fois plus rapide encore, puisque seul un sixième entier est en boucle. (Encore une fois, je l'ai comparé.)


Note latérale: x ** 0.5 est la racine carrée:

>>> import math
>>> math.sqrt(100)==100**0.5
True

Note 2: Test de primalité est un problème intéressant en informatique.

69
dawg

Avec n**.5, vous ne quadrillez pas n, mais vous prenez la racine carrée.

Considérons le nombre 20; les facteurs entiers sont 1, 2, 4, 5, 10 et 20. Lorsque vous divisez 20 par 2 et obtenez 10, vous savez qu'il est également divisible par 10, sans avoir à vérifier. Lorsque vous le divisez par 4 et obtenez 5, vous savez qu'il est divisible par 4 et par 5, sans qu'il soit nécessaire de vérifier 5.

Après avoir atteint ce point à mi-chemin dans les facteurs, vous n’avez plus de chiffres pour vérifier ceux que vous n’avez pas déjà reconnus comme facteurs auparavant. Par conséquent, il vous suffit de regarder à mi-chemin pour voir si quelque chose est primordial, et vous pouvez trouver ce point à mi-chemin en prenant la racine carrée du nombre.

De plus, la raison pour laquelle 1 n'est pas un nombre premier, c'est parce que les nombres premiers sont définis comme ayant 2 facteurs, 1 et lui-même. c'est-à-dire que 2 vaut 1 * 2, 3 vaut 1 * 3, 5 vaut 1 * 5. Mais 1 (1 * 1) n'a qu'un seul facteur, lui-même. Par conséquent, il ne correspond pas à cette définition.

19
cpuguy89

La question a été posée il y a un peu, mais j'ai une solution plus courte pour vous

isPrime(Number):
    return 2 in [Number,2**Number%Number]

L'opération mathématique retournera toujours 2 si le nombre est un nombre premier au lieu de 2. Mais si 2 est le nombre donné, il est ajouté à la liste que nous examinons.

2^5=32    32%5=2
2^7=128   128%7=2
2^11=2048 2048%11=2

etc ...

isPrime () renvoie True si Number est Prime et False sinon.

12
Daniel

Aucune opération en virgule flottante n'est effectuée ci-dessous. Ceci est plus rapide et tolérera des arguments plus élevés. La raison pour laquelle vous devez aller uniquement à la racine carrée est que si un nombre a un facteur plus grand que sa racine carrée, il a également un facteur plus petit que lui.

def is_prime(n):
    """"pre-condition: n is a nonnegative integer
    post-condition: return True if n is prime and False otherwise."""
    if n < 2: 
         return False;
    if n % 2 == 0:             
         return n == 2  # return False
    k = 3
    while k*k <= n:
         if n % k == 0:
             return False
         k += 2
    return True
10
ncmathsadist

Trouver la racine carrée du nombre est pour l'efficacité. par exemple. si j'essaie de trouver les facteurs de 36, le plus grand nombre pouvant être multiplié par lui-même pour former 36 est 6. 7 * 7 = 49. 

chaque facteur de 36 doit donc être multiplié par 6 ou un nombre inférieur. 

4
dibble
def is_prime(x):
    if x < 2:
        return False
    Elif x == 2:
        return True  
    for n in range(2, x):
        if x % n ==0:
            return False
    return True
4
likarson

Cette méthode sera plus lente que les méthodes récursives et énumératives ici, mais utilise le théorème de Wilson , et est juste une seule ligne:

from math import factorial

def is_prime(x):
    return factorial(x - 1)  % x == x - 1
3
aikramer2

Je ne sais pas si je suis en retard, mais je vais laisser ça ici pour aider quelqu'un à l'avenir.

Nous utilisons la racine carrée de (n), c’est-à-dire int (n ** 0,5) pour réduire la plage de nombres que votre programme sera forcé de calculer.

Par exemple, nous pouvons faire une division d’essai pour tester la primalité de 100. Examinons tous les diviseurs de 100:

2, 4, 5, 10, 20, 25, 50Voici, le facteur le plus important est 100/2 = 50. Cela est vrai pour tous les n: tous les diviseurs sont inférieurs ou égaux à n/2. Si nous examinons de plus près les diviseurs, nous verrons que certains d’entre eux sont redondants. Si nous écrivons la liste différemment:

100 = 2 × 50 = 4 × 25 = 5 × 20 = 10 × 10 = 20 × 5 = 25 × 4 = 50 × 2 La redondance devient évidente. Une fois que nous atteignons 10, soit √100, les diviseurs se retournent et se répètent. Par conséquent, nous pouvons éliminer davantage les diviseurs de test supérieurs à √n.

Prenez un autre numéro comme 16.

Ses diviseurs sont, 2,4,8

16 = 2 * 8, 4 * 4, 8 * 2.

Vous pouvez noter qu'après avoir atteint 4, qui est la racine carrée de 16, nous avons répété 8 * 2, ce que nous avions déjà fait en tant que 2 * 8. Ce modèle est vrai pour tous les nombres.

Pour éviter de nous répéter, nous testons donc la primalité jusqu'à la racine carrée d'un nombre n.

Nous convertissons donc la racine carrée en int car nous ne voulons pas de plage avec des nombres flottants.

Lisez le test de primalité sur wikipedia pour plus d'informations.

2
Stephen-Njoroge

Chaque code que vous écrivez doit être efficace. Pour un débutant comme vous, le plus simple est de vérifier la divisibilité du nombre 'n' de 2 à (n-1). Cela prend beaucoup de temps quand on considère de très grands nombres. La méthode de la racine carrée nous aide à rendre le code plus rapide en réduisant le nombre de comparaisons. En savoir plus sur complexités dans la conception et l'analyse d'algorithmes. 

2
Vipin Rai

Implémenté un pseudocode ( https://en.wikipedia.org/wiki/Primality_test ) en python, espérons cette aide.

# original pseudocode https://en.wikipedia.org/wiki/Primality_test
def isPrime(n):
    # Corner Cases
    if (n<= 1): return False
    Elif (n<= 3): return True
    Elif (n%2 == 0 or n%3 == 0): return False

    i = 5
    while i*i<=n:
        if (n%i==0 or n%(i+2)==0): return False
        i += 6

    return True;

%timeit isPrime(800)
1
madeinQuant
isPrime=lambda x: all(x % i != 0 for i in range(int(x**0.5)+1)[2:])

et voici comment l'utiliser

isPrime(2) == False
isPrime(5) == True
isPrime(7) == True

Pour trouver tous les nombres premiers, vous pouvez utiliser: 

filter(isPrime, range(4000)[2:])[:5]
=> [2, 3, 5, 7, 11]

Notez que 5, dans ce cas, indique le nombre de nombres premiers à trouver et la plage maximale de 4000 où les nombres premiers seront recherchés.

1
test30
def is_prime(x):  
    if x < 2:  
        return False  
    for n in range(2, (x) - 1):  
        if x % n == 0:  
            return False  
    return True
1
def isPrime(num,div=2):
    if(num==div):
        return True
    Elif(num % div == 0):
        return False
    else:
        return isPrime(num,div+1)

============================================
ÉDITÉ

def is_prime(num, div = 2):
    if num == div: return True
    Elif num % div == 0: return False
    Elif num == 1: return False
    else: return is_prime(num, div + 1)
1
namco

Ceci est ma façon np

def is_prime(x):
    if x < 4:
        return True
    if all([(x > 2), (x % 2 == 0)]):
        return False
    else:
        return np.array([*map(lambda y: ((x % y) == 0).sum(), np.arange(1, x + 1))]).sum() == 2

Voici la performance:

%timeit is_prime(2)
%timeit is_prime(int(1e3))
%timeit is_prime(5003)

10000 loops, best of 3: 31.1 µs per loop
10000 loops, best of 3: 33 µs per loop
10 loops, best of 3: 74.2 ms per loop
0
O.rka

int(n**0.5) est la valeur plancher de sqrt (n) que vous avez confondue avec la puissance 2 de n (n**2). Si n est not prime, il doit y avoir deux nombres 1 < i <= j < n tels que: i * j = n

Maintenant, puisque sqrt(n) * sqrt(n) = n suppose que l'un des i,j est supérieur (ou égal à) sqrt(n) - cela signifie que l'autre doit être inférieur à (ou égal à) sqrt(n).

Etant donné que c'est le cas, il est suffisant de répéter les nombres entiers compris dans la plage [2, sqrt(n)]. Et c'est exactement ce que le code qui a été posté fait.

Si vous voulez devenir un véritable smartass, utilisez la fonction à une ligne suivante:

import re
def is_prime(n):    
    return not re.match(r'^1?$|^(11+?)\1+$',n*'1')

On peut trouver une explication pour la "regex magique" ici

0
alfasin

C'était un exercice de codécademy et c'est comme ça que je l'ai passé en dessous ... 

def is_prime(x):  

    # If number(x) is evenly divided by following dividers then number(x) is not prime

    divider = [2, 3, 5, 7]

    # An empty list to be able to check whether number(x) is evenly divided:

    remainder = []

    # exceptions for numbers 1,2,3,5,7:
    if x < 2:
        return False
    if x in divider:
        return True
    else:
        for nums in divider:
            remainder.append(x % nums)
        if 0 in remainder:
            return False
        else:
            return True
0
Murat Karınca
def fun(N):#prime test
if N>1 :
    for _ in xrange(5):
        Num=randint(1,N-1)
        if pow(Num,N-1,N)!=1:
            return False
    return True
return False

Vrai si le nombre est premier sinon faux

0
chinmay rakshit
def is_prime(n):
    n=abs(n)
    if n<2:    #Numbers less than 2 are not prime numbers
        return "False"
    Elif n==2: #2 is a prime number
        return "True"
    else:
        for i in range(2,n): # Highlights range numbers that can't be  a factor of prime number n. 
            if n%i==0:
                return "False" #if any of these numbers are factors of n, n is not a prime number
    return "True" # This is to affirm that n is indeed a prime number after passing all three tests
0
Ayo