Mi algoritmo actual para comprobar la primalidad de los números en Python es manera de retardar de los números entre 10 millones y 1 mil millones. Quiero que se mejore sabiendo que nunca recibiré números mayores a mil millones.determinar rápidamente si un número es primo en Python para los números <1 mil millones
El contexto es que no puedo obtener una implementación que sea lo suficientemente rápida para resolver el problema 60 del proyecto Euler: obtengo la respuesta al problema en 75 segundos donde lo necesito en 60 segundos. http://projecteuler.net/index.php?section=problems&id=60
que tienen muy poca memoria a mi disposición lo que no puede almacenar todos los números primos por debajo de 1 mil millones.
actualmente estoy usando la división de prueba estándar sintonizado con 6k ± 1. ¿Hay algo mejor que esto? ¿Ya necesito obtener el método de Rabin-Miller para los números que son tan grandes?
primes_under_100 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
def isprime(n):
if n <= 100:
return n in primes_under_100
if n % 2 == 0 or n % 3 == 0:
return False
for f in range(5, int(n ** .5), 6):
if n % f == 0 or n % (f + 2) == 0:
return False
return True
¿Cómo puedo mejorar este algoritmo?
Precisión: Soy nuevo en Python y me gustaría trabajar con Python 3+ solamente.
código final
Para aquellos que estén interesados, utilizando las ideas de MAK, que genera el siguiente código que es aproximadamente un tercio más rápido, lo que me permite obtener el resultado del problema de Euler en menos de 60 segundos!
from bisect import bisect_left
# sqrt(1000000000) = 31622
__primes = sieve(31622)
def is_prime(n):
# if prime is already in the list, just pick it
if n <= 31622:
i = bisect_left(__primes, n)
return i != len(__primes) and __primes[i] == n
# Divide by each known prime
limit = int(n ** .5)
for p in __primes:
if p > limit: return True
if n % p == 0: return False
# fall back on trial division if n > 1 billion
for f in range(31627, limit, 6): # 31627 is the next prime
if n % f == 0 or n % (f + 4) == 0:
return False
return True
es este Py3k ??? – st0le
Lo conocía con el nombre Python 3 o Python 3.1, pero parece que Py3k hace referencia a estas versiones. –
no debería ser 'f' y' f + 4' ... ¿Podría confirmarlo? ¿por qué el '4'? – st0le