How to generate the 1000th prime in python?

跟風遠走 提交于 2019-12-05 19:02:20

问题


count = 0
i = 11

while count <= 1000 and i <= 10000:
    if i%2 != 0:
       if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
           continue
       else:
           print i,'is prime.'
           count += 1
    i+=1

I'm trying to generate the 1000th prime number only through the use of loops. I generate the primes correctly but the last prime i get is not the 1000th prime. How can i modify my code to do so. Thank in advance for the help.

EDIT: I understand how to do this problem now. But can someone please explain why the following code does not work ? This is the code I wrote before I posted the second one on here.

count = 1
i = 3
while count != 1000:
    if i%2 != 0:
       for k in range(2,i):
          if i%k == 0:
            print(i)
            count += 1
            break
     i += 1

回答1:


Let's see.

count = 1
i = 3
while count != 1000:
    if i%2 != 0:
       for k in range(2,i):
          if i%k == 0:        # 'i' is _not_ a prime!
            print(i)       # ??
            count += 1     # ??
            break
     i += 1          # should be one space to the left,
                     # for proper indentation

If i%k==0, then i is not a prime. If we detect that it's not a prime, we should (a) not print it out, (b) not increment the counter of found primes and (c) we indeed should break out from the for loop - no need to test any more numbers.

Also, instead of testing i%2, we can just increment by 2, starting from 3 - they will all be odd then, by construction.

So, we now have

count = 1
i = 3
while count != 1000:
    for k in range(2,i):
        if i%k == 0:       
            break
    else:
        print(i)
        count += 1
    i += 2        

The else after for gets executed if the for loop was not broken out of prematurely.

It works, but it works too hard, so is much slower than necessary. It tests a number by all the numbers below it, but it's enough to test it just up to its square root. Why? Because if a number n == p*q, with p and q between 1 and n, then at least one of p or q will be not greater than the square root of n: if they both were greater, their product would be greater than n.

So the improved code is:

from math import sqrt

count = 1
i = 1
while count < 1000:
    i += 2
    for k in range(2, 1+int(sqrt(i+1))):
        if i%k == 0:       
            break
    else:
        # print(i) ,
        count += 1
        # if count%20==0: print ""
print i

Just try running it with range(2,i) (as in the previous code), and see how slow it gets. For 1000 primes it takes 1.16 secs, and for 2000 – 4.89 secs (3000 – 12.15 ses). But with the sqrt it takes just 0.21 secs to produce 3000 primes, 0.84 secs for 10,000 and 2.44 secs for 20,000 (orders of growth of ~ n2.1...2.2 vs. ~ n1.5).

The algorithm used above is known as trial division. There's one more improvement needed to make it an optimal trial division, i.e. testing by primes only. An example can be seen here, which runs about 3x faster, and at better empirical complexity of ~ n1.3.


Then there's the sieve of Eratosthenes, which is quite faster (for 20,000 primes, 12x faster than "improved code" above, and much faster yet after that: its empirical order of growth is ~ n1.1, for producing n primes, measured up to n = 1,000,000 primes):

from math import log

count = 1 ; i = 1 ; D = {}
n = 100000                        # 20k:0.20s 
m = int(n*(log(n)+log(log(n))))   # 100k:1.15s 200k:2.36s-7.8M 
while count < n:                  #            400k:5.26s-8.7M 
        i += 2                    #            800k:11.21-7.8M 
        if i not in D:            #            1mln:13.20-7.8M (n^1.1)
            count += 1
            k = i*i
            if k > m:  break      # break, when all is already marked
            while k <= m:
                D[k] = 0 
                k += 2*i
while count < n:
        i += 2
        if i not in D: count += 1
if i >= m: print "invalid: top value estimate too small",i,m ; error
print i,m  

The truly unbounded, incremental, "sliding" sieve of Eratosthenes is about 1.5x faster yet, in this range as tested here.




回答2:


A couple of problems are obvious. First, since you're starting at 11, you've already skipped over the first 5 primes, so count should start at 5.

More importantly, your prime detection algorithm just isn't going to work. You have to keep track of all the primes smaller than i for this kind of simplistic "sieve of Eratosthanes"-like prime detection. For example, your algorithm will think 11 * 13 = 143 is prime, but obviously it isn't.

PGsimple1 here is a correct implementatioin of what the prime detection you're trying to do here, but the other algorithms there are much faster.




回答3:


Are you sure you are checking for primes correctly? A typical solution is to have a separate "isPrime" function you know that works.

def isPrime(num):
    i = 0
    for factor in xrange(2, num):
        if num%factor == 0:
            return False
    return True

(There are ways to make the above function more effective, such as only checking odds, and only numbers below the square root, etc.)

Then, to find the n'th prime, count all the primes until you have found it:

def nthPrime(n):
    found = 0
    guess = 1
    while found < n:
        guess = guess + 1
        if isPrime(guess):
            found = found + 1
    return guess



回答4:


your logic is not so correct. while :

if i%2 != 0:
    if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):

this cannot judge if a number is prime or not .

i think you should check if all numbers below sqrt(i) divide i .




回答5:


Here's a is_prime function I ran across somewhere, probably on SO.

def is_prime(n):
  return all((n%j > 0) for j in xrange(2, n))

primes = []

n = 1
while len(primes) <= 1000: 
    if is_prime(n):
        primes.append(n)
    n += 1

Or if you want it all in the loop, just use the return of the is_prime function.

primes = []    
n = 1
while len(primes) <= 1000: 
    if all((n%j > 0) for j in xrange(2, n)):
        primes.append(n)
    n += 1



回答6:


This is probably faster: try to devide the num from 2 to sqrt(num)+1 instead of range(2,num).

from math import sqrt

i = 2 
count = 1

while True:
    i += 1
    prime = True
    div = 2
    limit = sqrt(i) + 1
    while div < limit:
        if not (i % div):
            prime = False
            break
        else:
            div += 1
    if prime:
        count += 1
    if count == 1000:
        print "The 1000th prime number is %s" %i
        break



回答7:


Try this:

def isprime(num):
    count = num//2 + 1
    while count > 1:
        if num %count == 0:
            return False
        count -= 1
    else:
        return True

num = 0
count = 0
while count < 1000:
    num += 1
    if isprime(num):
        count += 1
    if count == 1000:
        prime = num

Problems with your code:

  1. No need to check if i <= 10000.
  2. You are doing this

    if i%2 != 0:
        if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
    

    Here, you are not checking if the number is divisible by a prime number greater than 7. Thus your result: most probably divisible by 11

  3. Because of 2. your algorithm says 17 * 13 * 11 is a prime(which it is not)




回答8:


How about this:

#!/usr/bin/python

from math import sqrt

def is_prime(n):
    if n == 2:
        return True
    if (n < 2) or (n % 2 == 0):
        return False
    return all(n % i for i in xrange(3, int(sqrt(n)) + 1, 2))

def which_prime(N):
    n = 2
    p = 1
    while True:
        x = is_prime(n)
        if x:
            if p == N:
                return n
            else:
                p += 1
        n += 1
print which_prime(1000)



回答9:


n=2                         ## the first prime no.
prime=1                     ## we already know 2 is the first prime no.
while prime!=1000:          ## to get 1000th prime no.
    n+=1                    ## increase number by 1
    pon=1                   ## sets prime_or_not(pon) counter to 1
    for i in range(2,n):    ## i varies from 2 to n-1
        if (n%i)==0:        ## if n is divisible by i, n is not prime
            pon+=1          ## increases prime_or_not counter if  n is not prime
    if pon==1:              ## checks if n is prime or not at the end of for loop
        prime+=1            ## if n is prime, increase prime counter by 1
print n                     ## prints the thousandth prime no.



回答10:


Here is yet another submission:

ans = 0;
primeCounter = 0;
while primeCounter < 1000:
    ans += 1;    
    if ans % 2 != 0: 
        # we have an odd number
        # start testing for prime
        divisor = 2;
        isPrime = True;
        while divisor < ans:
            if ans % divisor == 0: 
                isPrime = False;
                break;
            divisor += 1;
        if isPrime:             
            print str(ans) + ' is the ' + str(primeCounter) + ' prime';
            primeCounter += 1;
print 'the 1000th prime is ' + str(ans);



回答11:


Here's a method using only if & while loops. This will print out only the 1000th prime number. It skips 2. I did this as problem set 1 for MIT's OCW 6.00 course & therefore only includes commands taught up to the second lecture.

prime_counter = 0  
number = 3  

while(prime_counter < 999):
    divisor = 2
    divcounter = 0
    while(divisor < number):
        if(number%divisor == 0):
            divcounter = 1  
        divisor += 1
    if(divcounter == 0):
        prime_counter+=1
    if(prime_counter == 999):
        print '1000th prime number: ', number
    number+=2



回答12:


I just wrote this one. It will ask you how many prime number user wants to see, in this case it will be 1000. Feel free to use it :).

# p is the sequence number of prime series
# n is the sequence of natural numbers to be tested if prime or not
# i is the sequence of natural numbers which will be used to devide n for testing
# L is the sequence limit of prime series user wants to see
p=2;n=3
L=int(input('Enter the how many prime numbers you want to see: '))
print ('# 1  prime is 2')
while(p<=L):
    i=2
    while i<n:
        if n%i==0:break
        i+=1
    else:print('#',p,' prime is',n); p+=1
    n+=1 #Line X

#when it breaks it doesn't execute the else and goes to the line 'X' 


来源:https://stackoverflow.com/questions/15400108/how-to-generate-the-1000th-prime-in-python

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