Quantcast
Channel: Sieve of Eratosthenes - Finding Primes Python - Stack Overflow
Viewing all articles
Browse latest Browse all 28

Answer by KevinBui for Sieve of Eratosthenes - Finding Primes Python

$
0
0

Basic sieve

with numpy is amazing fast. May be the fastest implementation

# record: sieve 1_000_000_000 in 6.9s (core i7 - 2.6Ghz)def sieve_22max_naive(bound):    sieve = np.ones(bound, dtype=bool)  # default all prime    sieve[:2] = False  # 0, 1 is not prime    sqrt_bound = math.ceil(math.sqrt(bound))    for i in range(2, sqrt_bound):        if sieve[i]:            inc = i if i == 2 else 2 * i            sieve[i * i:bound:inc] = False    return np.arange(bound)[sieve]if __name__ == '__main__':    start = time.time()    prime_list = sieve_22max_naive(1_000_000_000)    print(f'Count: {len(prime_list):,}\n'          f'Greatest: {prime_list[-1]:,}\n'          f'Elapsed: %.3f' % (time.time() - start))

Segment sieve (use less memory)

# find prime in range [from..N), base on primes in range [2..from)def sieve_era_part(primes, nfrom, n):    sieve_part = np.ones(n - nfrom, dtype=bool)  # default all prime    limit = math.ceil(math.sqrt(n))    # [2,3,5,7,11...p] can find primes < (p+2)^2    if primes[-1] < limit - 2:        print(f'Not enough base primes to find up to {n:,}')        return    for p in primes:        if p >= limit: break        mul = p * p        inc = p * (2 if p > 2 else 1)        if mul < nfrom:            mul = math.ceil(nfrom / p) * p            (mul := mul + p) if p > 2 and (mul & 1) == 0 else ...  # odd, not even        sieve_part[mul - nfrom::inc] = False    return np.arange(nfrom, n)[sieve_part]    # return np.where(sieve_part)[0] + nfrom    # return [i + nfrom for i, is_p in enumerate(sieve_part) if is_p]    # return [i for i in range(max(nfrom, 2), n) if sieve_part[i - nfrom]]# find nth prime number, use less memory,# extend bound to SEG_SIZE each loop# record: 50_847_534 nth prime in 6.78s, core i7 - 9850H 2.6GHhzdef nth_prime(n):    # find prime up to bound    bound = 500_000    primes = sieve_22max_naive(bound)    SEG_SIZE = int(50e6)    while len(primes) < n:        # sieve for next segment        new_primes = sieve_era_part(primes, bound, bound + SEG_SIZE)        # extend primes        bound += SEG_SIZE        primes = np.append(primes, new_primes)    return primes[n - 1]if __name__ == '__main__':    start = time.time()    prime = nth_prime(50_847_534)    print(f'{prime:,} Time %.6f' % (time.time() - start))

Viewing all articles
Browse latest Browse all 28

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>