Premier nombre 2 en Python

Poursuite de Prime in Python et Prime in Haskell 2. L'itérateur et le générateur n'étaient pas clairs, j'ai donc essayé de générer un nombre premier.

C'est celui que je vois habituellement.

from itertools import ifilter, count, dropwhile
def sieve():
  g = count(2)
  while True:
    prime = g.next()
    yield prime
    g = ifilter(lambda x, prime=prime: x % prime, g)


first_prime_GE_sieve = (lambda n , ps = sieve() : 
  (dropwhile( lambda x : x < n, ps ) ).next()
)
    
print first_prime_GE_sieve(52951)
#résultat
52951

(Tous les résultats sont le nombre maximum qui peut être calculé dans paiza.io sans délai. Pas toujours le même, mais comme un guide pour la vitesse.)

Je vois. Lors de la sortie d'un nombre premier, on a l'impression de passer au crible un itérateur de longueur infinie. Bien joué.

Une fois que vous aurez compris le contenu, vous remarquerez qu'il s'agit du code du commentaire que vous avez reçu ci-dessus. Seule la différence entre une fonction et un objet.

N'est-ce pas trop rapide?

Comment faire le quartier Haskell.

primes :: Integral a => [a]
primes = map fromIntegral $ [2, 3] ++ primes'

primes'  = [5] ++ recursivePrimes 1 7 primes'

recursivePrimes m s (p : ps) = 
  zonedPrimes m s p ++ recursivePrimes (m * p) (p * p) ps

zonedPrimes m s p = 
  [n | n <- croppedPrimables s p, gcd m n == 1] 

croppedPrimables s p = 
  [x + y | x <- [s, s + 6 .. p * p - 6], y <- [0, 4]]
  
main = print . take 1 . dropWhile (<24684009) $ primes
--résultat
[24684013]

Il est transformé pour qu'il soit facile à comprendre. L'original est ici.

C'est comme calculer petit à petit et construire. C'est assez rapide.

Je vais l'apporter là-bas.

Essayons cet algorithme en Python.

from fractions import gcd
from itertools import chain, tee, dropwhile

cropped_primables = (lambda s, p :
  [x + y for x in xrange(s,p * p - 5, 6) for y in [0, 4]]
)

zoned_primes = (lambda m, s, p :
  [n for n in cropped_primables(s, p) if gcd(m, n) == 1]
)

def primes() :
 
  primes_list = [2, 3, 5]
  last_prime = primes_list[-1] 
  primes_iter = iter(primes_list)

  seeds_iter = iter([])
  m = 1
  s = 7
  p = 5

  while True :
    prime = primes_iter.next()
    yield prime

    if prime == last_prime :
      primes_list = zoned_primes(m, s, p)
      last_prime = primes_list[-1]
      
      it1, it2 = tee(primes_list)
      primes_iter = it1
      seeds_iter = chain(seeds_iter, it2)
      
      m = m * p
      s = p * p
      p = seeds_iter.next()

first_prime_GE = (lambda n , ps = primes() : 
  (dropwhile( lambda x : x < n, ps ) ).next()
)
    
print first_prime_GE(3003079)
#résultat
3003079

Haskell utilise l'évaluation paresseuse, alors que faire avec Python?

Cependant, en tant qu'algorithme, il est seulement nécessaire de connaître le prochain nombre premier, j'ai donc conçu un itérateur séparément pour renvoyer une valeur et pour calculer un nombre premier en interne.

Au fait, c'est simple, mais si vous essayez Exécuter une fois et mesurer le temps avec l'argument 100000 sur IDLE

>>> measure_t(first_prime_GE,100000)
2.5987625122070312e-05

Environ 0,026 milliseconde.

Au début

>>> measure_t( first_prime_GE_sieve,100000)
16.222843885421753

Environ 16 secondes.

N'est-ce pas assez rapide?

Postscript

J'ai essayé de ne pas provoquer d'erreur d'exécution ci-dessus, mais est-ce généralement comme ça?

# coding: utf-8
from fractions import gcd
from itertools import chain, tee, dropwhile

cropped_primables = (lambda s, p :
  (x + y for x in xrange(s,p * p - 5, 6) for y in [0, 4])
)

zoned_primes = (lambda m, s, p :
  (n for n in cropped_primables(s, p) if gcd(m, n) == 1)
)

def primes() :
  primes_iter = iter([2, 3, 5])

  seeds_iter = iter([])
  m = 1
  s = 7
  p = 5

  while True :
    try :
      prime = primes_iter.next()
      
    except StopIteration :
      primes_base_iter = zoned_primes(m, s, p)
      
      it1,it2 = tee(primes_base_iter)
      primes_iter = it1
      seeds_iter = chain(seeds_iter, it2)
      
      m = m * p
      s = p * p
      p = seeds_iter.next()
      
    else :   
      yield prime

first_prime_GE = (lambda n , ps = primes() : 
  (dropwhile( lambda x : x < n, ps ) ).next()
)

print first_prime_GE(2728100)
##résultat
2728129

Changé pour capturer et traiter StopIteration. Passez à l'itérateur s'il ne s'agit pas d'un tableau.

Ça a l'air bien. Mais cela semble un peu tard.

De même, si vous mesurez le temps d'exécution

>>> measure_t(first_prime_GE,100000)
3.409385681152344e-05

0,034 millisecondes.

Recommended Posts

Premier nombre 2 en Python
Générateur principal infini en Python3
Nombre premier en Python
Projet Euler # 7 "1000 1er nombre premier" en Python
[Python 3] Décomposition des facteurs premiers en 14 lignes
Énumération des nombres premiers et jugement des nombres premiers en Python
Reconnaissance des nombres dans les images avec Python
Générateur de nombres premiers par Python
Énumération des nombres premiers sur une ligne
Etude, jeu de numérotation avec Python
Quadtree en Python --2
Python en optimisation
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Géocodage en python
SendKeys en Python
Méta-analyse en Python
Unittest en Python
Époque en Python
Allemand en Python
DCI en Python
tri rapide en python
nCr en python
N-Gram en Python
Programmation avec Python
Plink en Python
Constante en Python
FizzBuzz en Python
Sqlite en Python
Étape AIC en Python
LINE-Bot [0] en Python
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
Constante en Python
nCr en Python.
format en python
PPAP en Python
Quad-tree en Python
Réflexion en Python
Chimie avec Python
Hashable en Python
DirectLiNGAM en Python
LiNGAM en Python
Aplatir en Python
Aplatir en python
Projet Euler # 3 "Maximum Prime Factors" en Python
J'ai cherché un nombre premier avec python
Projet Euler # 17 "Nombre de caractères" en Python
Un programme qui détermine si un nombre entré en Python est un nombre premier
Liste triée en Python
AtCoder # 36 quotidien avec Python
Texte de cluster en Python
AtCoder # 2 tous les jours avec Python
Daily AtCoder # 32 en Python