Finding the nth Prime - python

I am trying to create an algorithm which will output the nth prime number. I have written up the code but whenever I run it I am given the 980th prime, when it should output the 1000th prime?
testNumber = 1
countPrimes = 0
testCounter = 2
isPrime = False
currentPrime = 0
while(countPrimes <= 1021): #runs for the first 1k primes
testCounter=2
isPrime = True
if(testNumber%2 != 0): #checks if test number is odd
while(testCounter*testCounter < testNumber): #counter^2 needs to be less than testNumber
if(testNumber%testCounter == 0):
isPrime = False
testCounter = testCounter + 1
if(isPrime==True):
countPrimes = countPrimes + 1
currentPrime = testNumber
testNumber+=1
print currentPrime

The problem is that your code is also counting odd perfect squares (9, 25, 49, etc) as prime numbers. That is because your code stops testing for divisibility just before you get to the square root of the number. To exclude perfect squares, you need to check one more integer:
I.e. instead of:
while(testCounter*testCounter < testNumber): #counter^2 needs to be less than testNumber
try this:
while(testCounter*testCounter < testNumber + 1): #counter^2 needs to be less than testNumber
Additionally, you'll still be one off because your code counts 0 and 1 as prime, and doesn't count 2.

Related

Understanding the logic of this prime number generator output

This code is meant to output prime numbers within a given range:
def sqrt(n):
return n**0.5
# find primes
def primes(minNum, maxNum):
primes_sum = 0
for i in range(minNum, maxNum):
current_max = int(sqrt(i))
for n in range(2, current_max + 1):
if(i%n == 0):
break
else:
primes_sum += i
print(i)
break
print('\nSum of all primes: ', primes_sum)
primes(10, 20)
However, I get an incorrect output:
11, 13, 15, 17, 19
Does someone know how the 15 manages to appear? I put print statements in the first if statement block to verify that 15 is detected by the if(i%n == 0) condition, and it is, but somehow it still appears in my final output and I can't figure out why.
I made changes to your code. Try in this way:
def sqrt(n):
return n**0.5
# find primes
def primes(minNum, maxNum):
primes_sum = 0
for i in range(minNum, maxNum):
current_max = int(sqrt(i))
#print(current_max)
flag = True
for n in range(2, current_max + 1):
#print(i,n)
if(i%n == 0):
flag = False
if flag:
print(i)
primes_sum += i
print('\nSum of all primes: ', primes_sum)
primes(10, 200)
In your code, you are not checking whether all the number is divisible by all the numbers. It will fail for all the odd non-prime numbers as it will check whether it is divisible by 2, if not it is a prime number
This logic:
for n in range(2, current_max + 1):
if(i%n == 0):
break
else:
primes_sum += i
print(i)
break
doesn't work to detect prime numbers, because if the first value of n you test (which will be 2) isn't a factor, you'll immediately count it as a prime and break the loop. You need to finish iterating over the entire range before deciding a number is a prime:
for n in range(2, current_max + 1):
if i % n == 0:
break
else:
primes_sum += i
print(i)
Note that the else is part of the for, not the if -- it only executes if the for loop exhausts itself without ever hitting a break (i.e. if it doesn't find any n values that are factors of i).
The reason is perfectly explained by #SAI SANTOSH CHIRAG. I won't copy that. I'm not sure why you're using sqrt of a number. You can do the stuff without sqrt. You would get wrong output if you use sqrt. In your case, if we check for sqrt of 18, then int of it would be 4 and the divisibility is checked from 2 to 4 whereas 18 is also divisible by 6. I am designing a new code without sqrt and explaining it as well.
My logic: define a function that takes upper bound and lower bound as parameter. Take a for loop ranging from lower bound to upper bound. Now each value will be a number between the range. We've to check whether the number is prime. Use loop ranging from 2 to number and check whether it is divisible or not. If yes, it is not prime. If no, add it to sum. Your code:
def primes(low,upp):
su=[]
for i in range(low,upp+1):
f=True
for j in range(2,i):
if i%j==0:
f=False
if f:
su.append(i)
return su,sum(su)
print(primes(10,20))

While loop doesn't read condition

I'm trying to make a program that will stop when it gets 5 prime numbers from a range.
I've completed most of the program except the part where it is supposed to stop after it gets 5 numbers.
I've added a condition for it to stop, once the counter reaches 5 but it does not stop and continues to list all the numbers in the range.
Here is code I have:
condition = 0
while condition < 5:
for numbers in range(2,20):
for divisor in range(2,numbers):
if (numbers % divisor) == 0:
break
else:
print(numbers)
condition +=1
The condition+=1 never goes through and it lists all the prime numbers from 1 to 20 even though I just want the first 5.
I've tried spacing options with the "condition +=1" but it still does not work
Any help would be appreciated
While is out of for loop, so cannot work obviously. A simple solution is to check required condition later:
for numbers in range(2,20):
for divisor in range(2,numbers):
if (numbers % divisor) == 0:
break
else:
print(numbers)
condition +=1
if condition >=5:
break
I think the real problem you are having is that you have written bad code. A much better approach to this problem is to isolate as many pieces as possible.
for example:
def is_prime(x):
"return true if x is prime, otherwise false"
# implement me!
return True
def get_first_n_primes_less_than_y(n, y):
number = 2
condition = 0
while condition != n and number < y:
if is_prime(number):
print(number)
condition += 1
number += 1
get_first_n_primes(5, 20)
The above code, with some tweaking can perform the same task. However, code like this is much simpler to debug and reason about because we have isolated chunks of code (is_prime, has nothing to do with the while loop)
num_results = 5
counter = 0
range_start = 2
range_end = 20
# iterate range
for number in range (range_start, range_end):
# iterate divisors
for divisor in range (2, number):
# check division
if (number % divisor) == 0:
break
else:
print ("%s is a prime number" % number)
counter += 1
break
# check if number of results has been reached
if counter == num_results:
break
# check if number of results has been reached
if counter == num_results:
break
The problem is that you need to run the entire content of the while block before you test the condition again.
Here is a way around
condition = 0
numbers=2
while condition < 5 and numbers < 20:
for divisor in range(2,numbers):
if (numbers % divisor) == 0:
break
else:
print(numbers)
condition +=1
numbers+=1

Enumeration to find Nth prime with Python

I have decided it is about time that i should start learning to code. I have some knowledge of HTML and CSS but i want to be able to develop for iOS. I am aware i have a long way to go, but i aim to get there step by step.
I'm working through the MIT Python course on iTunes U and I am stuck on the homework. I understand the concept of enumeration and testing every possible outcome to find the primes, however what i have tried so far has failed me. My closest attempt is the following.
# counting confirmed primes. For loop should do remainder tests on
# all testNumbers, unless caught by the if statements that rule out
# multiples of 2,3,5,7 to speed things up. divisor increments by one
# on those numbers that do not get pulled by qualifying if statements
testNumber = 2
confirmedPrime = 0
while (confirmedPrime < 1001):
for divisor in range(1, testNumber+1):
if (testNumber/2)*2== testNumber:
testNumber += 1
elif (testNumber/3)*3 == testNumber:
testNumber += 1
elif (testNumber/5)*5 == testNumber:
testNumber += 1
elif (testNumber/7)*7 == testNumber:
testNumber += 1
elif(testNumber%divisor == 0):
testNumber += 1
confirmedPrime +=1
print testNumber
This however doesn't return the "7919" i am expecting but. It returns "7507" So somewhere there are some composites slipping through the net.
I have hunted through this site and not managed to solve it so I thought I would ask.
A few bits are off here, so let's go step by step.
You start by setting initial values, which is perfectly reasonable.
testNumber=2
confirmedPrime = 0
Then you go into a while loop, continuing until the value of the variable confirmedPrime is has reached (i.e. is equal to or bigger than) 1001. I suppose your task is to find the 1000th prime, but doing it like this you're actually finding the 1001st, because the while loop continues until confirmedPrime has the value of 1001. Change it to
while(confirmedPrime < 1000):
You immediately go into another loop, and here comes the first problem, even though it isn't what's giving you the wrong answer.
for divisor in range(1, testNumber+1)
if (testNumber/2)*2 == testNumber:
...
Doing the tests for multipliers of 2, 3, 5 and 7 inside the for loop doesn't make any sense, as you only have to to this once for each value of testNumber. So that part of the testing should be moved out of the for loop.
if (testNumber/2)*2 = testNumber: # Why not use modulo here too for consistency?
testNumber += 1
elif ...
...
else:
for divisor in range(...):
The next part is testing for other, larger divisors. You are testing divisors in the range 1 to testNumber+1. I'm not sure why you're doing this, but it's not a good idea, as your modulo test will always return zero when you come to the second last iteration, testing testNumber%testNumber. So you should change it to testNumber-1, in fact you can stop when you have reached the square root of testNumber, but I'll leave it to you to figure out why.
Now comes the biggest problem:
After the for loop is finished, you increment confirmedPrimes by 1 without actually checking if you found a prime or not. So, incrementing confirmedPrimes should only happen if none of the first tests were true and none of the "divisor tests" turned out to be true.
Rewritten using underscores instead of mixedCase (which is bad python mojo), consistent spacing etc:
import math
test_number = 7 # Already know up to 7
confirmed_primes = 4 # Already know about 2, 3, 5 and 7
while confirmed_primes < 1000:
test_number += 1
if test_number % 2 and test_number % 3 and test_number % 5 and test_number % 7:
is_prime = True
for divisor in range(11, int(math.sqrt(test_number))+1):
if test_number % divisor == 0:
is_prime = False
if is_prime:
confirmed_primes += 1
print test_number
I don't understand exactly how your algorithm is supposed to find a prime number.
A number is said to be prime if it's only divisible by 1 or himself.
Another definition is that a number is said to be prime if it's not divisible by any prime number smaller than it.
This can be the base of your algorithm, speeding up the process by a lot.
def nth_prime(n):
prime_list = []
current = 2
count = 0
while(count < n):
is_prime = True
for prime in prime_list:
if current % prime == 0:
is_prime = False
break
if is_prime:
prime_list.append(current)
count += 1
current += 1
return current - 1
print nth_prime(1000) # => 7919

Prime number generator is not working Python

What I want to do is:
create a "list" of odd numbers
then test if they are prime
the test will be done with multiples up to half of the value of the odd number hence halfodd
put the prime number into a list
print that list
however my result is a list of numbers from 1 to 1003 that skip 3, 4, and 5
Is there a semantic error here?
#Prime number generator
def primenumber():
primelist = [1, 2]
num = 3
even = num%2
multi = 0
result = 0
while len(primelist) < 1000:
if even != 0:
oddnum = num
i = 2
halfodd = ((oddnum + 1)/2)
while i < halfodd:
i =+ 1
multi = oddnum%i
if multi == 0:
result += 1
if result != 0:
primelist.append(oddnum)
prime_num = oddnum
num += 1
print primelist
primenumber()
if result != 0:
Since result is (supposed to be) a count of how many factors you found, you want
if result == 0:
You're also not resetting result when you advance to a new candidate prime, you never recompute even, and if you did, you'd be considering the odd numbers twice each.
This should work:
def primenumber():
primelist = [1, 2]
candidate = 3
while len(primelist) < 1000:
isCandidatePrime = True
if (candidate % 2 == 0): # if candidate is even, not a prime
isCandidatePrime = False
else:
for i in range(3, (candidate+1)/2, 2): # else check odds up to 1/2 candidate
if (candidate % i == 0): # if i divides it, not a prime
isCandidatePrime = False
break
if (isCandidatePrime):
primelist.append(candidate)
candidate += 1
print primelist
I think there are several improvements (check only numbers less than or equal to the square root of the candidate, only check prime numbers, not all numbers less than the square root of the candidate) but I'll leave that alone for now.

How to generate the 1000th prime in python?

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
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.
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.
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
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 .
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
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
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:
No need to check if i <= 10000.
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
Because of 2. your algorithm says 17 * 13 * 11 is a prime(which it is not)
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)
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.
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);
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
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'
This will be the optimized code with less number of executions, it can calculate and display 10000 prime numbers within a second.
it will display all the prime numbers, if want only nth prime number, just set while condition and print the prime number after you come out of the loop. if you want to check a number is prime or not just assign number to n, and remove while loop..
it uses the prime number property that
* if a number is not divisible by the numbers which are less than its square root then it is prime number.
* instead of checking till the end(Means 1000 iteration to figure out 1000 is prime or not) we can end the loop within 35 iterations,
* break the loop if it is divided by any number at the beginning(if it is even loop will break on first iteration, if it is divisible by 3 then 2 iteration) so we iterate till the end only for the prime numbers
remember one thing you can still optimize the iterations by using the property *if a number is not divisible with the prime numbers less than that then it is prime number but the code will be too large, we have to keep track of the calculated prime numbers, also it is difficult to find a particular number is a prime or not, so this will be the Best logic or code
import math
number=1
count = 0
while(count<10000):
isprime=1
number+=1
for j in range(2,int(math.sqrt(number))+1):
if(number%j==0):
isprime=0
break
if(isprime==1):
print(number,end=" ")
count+=1

Categories