Finding the 10001st prime - how to optimize?

China☆狼群 提交于 2019-12-13 05:54:24

问题


Project Euler problem 7 says:

By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the 10001st prime number?

Here's the code I've written in Python:

def primes(n):
    primes = []
    attempt = 3
    while len(primes) < (n-1):
        for i in range(len(primes)):
            if attempt % primes[i] == 0:
                attempt += 2
                break
        else:
            primes.append(attempt)
            print (primes)
    return (primes)

While testing a number, if it finds that the number is divisible by one of the primes in the list, the for loop breaks, and starts again with a larger number. If it isn't divisible, it's added to the list of primes. This keeps going until the list is as large as desired (in this case 10000, and I've omitted 2 so the last member of the list is the 10001st prime)

The problem is that this is extremely SLOW. I've seen other solutions that can apparently solve this is seconds, if not less. What are some ways I could make this fun faster?


回答1:


These are optimizations problems, so you don't want to be printing every time you update the list. The other thing is don't use list at all because is not very memory efficient. You should use instead generators. Its very fast and you don't get to consume memory using lists. Below is a code for this purpose, watch how the yield keyword is being used in order to convert count_primes function into a generator.

def is_prime(num):
    """
    Checks if a number is prime
    """
    prime_counter = 1
    for x in range(1, num):
        if num % x == 0:
            prime_counter += 1
        if prime_counter > 2:
            return False
    return True


def count_primes():
    """
    Counts primes until PRIMES_TO_COUNT
    is reached
    """
    PRIMES_TO_COUNT = 1000       # Modify this value
    prime_counter_num = 0
    start_point_num = 1
    while True:
        if is_prime(start_point_num):
            if prime_counter_num == PRIMES_TO_COUNT:
                yield start_point_num
                print "This is the %dth prime number: %s" \
                      % (prime_counter_num, start_point_num)
                break
            prime_counter_num += 1
        start_point_num += 1


if __name__ == '__main__':
    for prime_number in count_primes():
        print prime_number

Hope this helps you!. Python generators!




回答2:


Instead of checking for every odd number you can check for all numbers of the form 6n±1 because all primes are of that form.



来源:https://stackoverflow.com/questions/32333888/finding-the-10001st-prime-how-to-optimize

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!