Project Euler #7: 10001st prime

  • + 0 comments

    here is my fastest implementation of this in python using sieve of atkin:

    import math
    
    def sieve_of_atkin(limit):
        sieve = [False] * (limit + 1)
        sieve[2], sieve[3] = True, True
        
        for x in range(1, int(math.sqrt(limit)) + 1):
            for y in range(1, int(math.sqrt(limit)) + 1):
                n = 4 * x**2 + y**2
                if n <= limit and (n % 12 == 1 or n % 12 == 5):
                    sieve[n] = not sieve[n]
                
                n = 3 * x**2 + y**2
                if n <= limit and n % 12 == 7:
                    sieve[n] = not sieve[n]
                
                n = 3 * x**2 - y**2
                if x > y and n <= limit and n % 12 == 11:
                    sieve[n] = not sieve[n]
    
        for x in range(5, int(math.sqrt(limit)) + 1):
            if sieve[x]:
                for y in range(x**2, limit + 1, x**2):
                    sieve[y] = False
        
        return sieve
    
    def count_primes(sieve):
        return [i for i in range(2, len(sieve)) if sieve[i]]
    
    def nth_prime_fast(n):
        if n < 1:
            return None
        if n == 1:
            return 2
        
        limit = max(10, n * int(math.log(n) + math.log(math.log(n))))
        while True:
            sieve = sieve_of_atkin(limit)
            primes = count_primes(sieve)
            if len(primes) >= n:
                return primes[n - 1]
            limit *= 2
    
    
    print(nth_prime_fast(10001))