Problem with finding 10,001th prime number: 1 off - python

"""7. 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 10 001st prime number?"""
countprime=0
n=2
def prime(number):
for factors in range(2, number):
if number%factors==0:
return False
break
return True
while countprime!=10001:
if prime(n)==True:
countprime+=1
n+=1
print(n)
The answer is supposed to be 104743, but for some reason my brute force program gets 104744, 1 more. Does anyone know why it is one off?

while countprime != 10001:
if prime(n)==True:
countprime+=1
n+=1
When you find a prime number, you always move on to the next number. So, after finding the correct answer, you add up 1 and get 104744.
Try to firstly add 1, and then check if it's prime.
Here is an example:
n = 1
while countprime != 10001:
n += 1
if prime(n):
countprime += 1

You need to break your loop immediately when countprime == 10001 to leave your variable n untouched. A possible way:
while True:
countprime += prime(n)
if countprime == 10001:
break
n += 1

After your program finds the 10001th prime, the value of n is increased by 1 therefore your output is 1 more than the expected answer.
If you use print(n-1), your program will behave as expected.

You're increasing n one last time before your loop exits. If you increase n before checking if it's prime then your countPrime counter and the corresponding prime number will stay in sync (but you'll have to start n at 1 instead of 2):
n = 1
while countprime != 10001:
n += 1
if prime(n):
countprime += 1

Related

Prime checker including non primes

I am trying to solve Project Euler number 7.
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 10 001st prime number?
First thing that came into my mind was using length of list. This was very ineffective solution as it took over a minute. This is the used code.
def ch7():
primes = []
x = 2
while len(primes) != 10001:
for i in range(2, x):
if x % i == 0:
break
else:
primes.append(x)
x += 1
print(primes[-1])
ch7()
# Output is: 104743.
This works well but I wanted to reach faster solution. Therefore I did a bit of research and found out that in order to know if a number is a prime, we need to test whether it is divisible by any number up to its square root e.g. in order to know if 100 is a prime we dont need to divide it by every number up to 100, but only up to 10.
When I implemented this finding weird thing happened. The algorithm included some non primes. To be exact 66 of them. This is the adjusted code:
import math
primes = []
def ch7():
x = 2
while len(primes) != 10001:
for i in range(2, math.ceil(math.sqrt(x))):
if x % i == 0:
break
else:
primes.append(x)
x += 1
print(primes[-1])
ch7()
# Output is 104009
This solution takes under a second but it includes some non primes. I used math.ceil() in order to get int instead of float but I figured it should not be a problem since it still tests by every int up to square root of x.
Thank you for any suggestions.
Your solution generates a list of primes, but doens't use that list for anything but extracting the last element. We can toss that list, and cut the time of the code in half by treating 2 as a special case, and only testing odd numbers:
def ch7(limit=10001): # assume limit is >= 1
prime = 2
number = 3
count = 1
while count < limit:
for divisor in range(3, int(number ** 0.5) + 1, 2):
if number % divisor == 0:
break
else: # no break
prime = number
count += 1
number += 2
return prime
print(ch7())
But if you're going to collect a list of primes, you can use that list to get even more speed out of the program (about 10% for the test limits in use) by using those primes as divisors instead of odd numbers:
def ch7(limit=10001): # assume limit is >= 1
primes = [2]
number = 3
while len(primes) < limit:
for prime in primes:
if prime * prime > number: # look no further
primes.append(number)
break
if number % prime == 0: # composite
break
else: # may never be needed but prime gaps can be arbitrarily large
primes.append(number)
number += 2
return primes[-1]
print(ch7())
BTW, your second solution, even with the + 1 fix you mention in the comments, comes up with one prime beyond the correct answer. This is due to the way your code (mis)handles the prime 2.

listing prime numbers from 3 to 21 in python 3

for x in range (3,21):
if(x%2==0):
print (x,'is a not a prime number')
else:
print (x,'is a prime number')
This is my code but when it prints it says 9 is a prime number and 15 is a prime number.
Which is wrong because they aren't so how do I fix that?
.
def isPrime(N):
i = 2
while i**2 <= N:
if N % i == 0:
return False
i+=1
return True
for i in range(3, 21 + 1):
if isPrime(i):
print(i, 'is prime')
else:
print(i, 'is not a prime number')
First of all, create a function for determining whether or not a given number is prime (this is not a requirement but just a good practice). That function is not that hard: it just starts at i = 2 (starting at 1 makes no sense because every number can be divided by it) and check if N can be divided by it. If that is the case, we have found a divisor of N and thus, it isnt prime. Otherwise, continue with the next number: i += 1. The most tricky part of the loop is the stoping condition: i**2 <= N: we dont have to look further, because if some j > i is a divisor of N, then there is some other k < i that is also a divisor of N: k * j == N. If such k exists, we will find it before getting to the point where i * i == N. Thats all. After that, just iterate over each number you want to check for primality.
Btw, the best way to check for the primality of a set of number is using the Sieve of Eratosthenes
Your code only checks if a number is even. All odd numbers are not prime. So write a for-loop that checks if a odd number is divisible by any of the odd number less than that. Sometying like:
For i in (3 to n): If n mod i == 0, n is not prime.

Finding primes in python

I know that python is "slow as dirt", but i would like to make a fast and efficient program that finds primes. This is what i have:
num = 5 #Start at five, 2 and 3 are printed manually and 4 is a multiple of 2
print("2")
print("3")
def isPrime(n):
#It uses the fact that a prime (except 2 and 3) is of form 6k - 1 or 6k + 1 and looks only at divisors of this form.
i = 5
w = 2
while (i * i <= n): #You only need to check up too the square root of n
if (n % i == 0): #If n is divisable by i, it is not a prime
return False
i += w
w = 6 - w
return True #If it isnĀ“t ruled out by now, it is a prime
while True:
if ((num % 2 != 0) and (num % 3 != 0)): #save time, only run the function of numbers that are not multiples of 2 or 3
if (isPrime(num) == True):
print(num) #print the now proved prime out to the screen
num += 2 #You only need to check odd numbers
Now comes my questions:
-Does this print out ALL prime numbers?
-Does this print out any numbers that aren't primes?
-Are there more efficient ways(there probably are)?
-How far will this go(limitations of python), and are there any ways to increase upper limit?
Using python 2.7.12
Does this print out ALL prime numbers?
There are infinitely many primes, as demonstrated by Euclid around 300 BC. So the answer to that question is most likely no.
Does this print out any numbers that aren't primes?
By the looks of it, it doesn't. However, to be sure; why not write a unit test?
Are there more efficient ways(there probably are)? -How far will this go(limitations of python), and are there any ways to increase upper limit?
See Fastest way to list all primes below N or Finding the 10001st prime - how to optimize?
Checking for num % 2 != 0 even though you increment by 2 each time seems pointless.
I have found that this algorithm is faster:
primes=[]
n=3
print("2")
while True:
is_prime=True
for prime in primes:
if n % prime ==0:
is_prime=False
break
if prime*prime>n:
break
if is_prime:
primes.append(n)
print (n)
n+=2
This is very simple. The function below returns True if num is a prime, otherwise False. Here, if we find a factor, other than 1 and itself, then we early stop the iterations because the number is not a prime.
def is_this_a_prime(num):
if num < 2 : return False # primes must be greater than 1
for i in range(2,num): # for all integers between 2 and num
if(num % i == 0): # search if num has a factor other than 1 and itself
return False # if it does break, no need to search further, return False
return True # if it doesn't we reached that point, so num is a prime, return True
I tried to optimize the code a bit, and this is what I've done.Instead of running the loop for n or n/2 times, I've done it using a conditional statements.(I think it's a bit faster)
def prime(num1, num2):
import math
def_ = [2,3,5,7,11]
result = []
for i in range(num1, num2):
if i%2!=0 and i%3!=0 and i%5!=0 and i%7!=0 and i%11!=0:
x = str(math.sqrt(i)).split('.')
if int(x[1][0]) > 0:
result.append(i)
else:
continue
return def_+result if num1 < 12 else result

Why won't my code do literally anything?

I'm trying to write some code to compute the thousandth prime number and when I thought I was done I tried to run it but nothing is happening. I don't get errors or anything that should happen according to the code, just literally nothing. I'm running it in windows powershell if that matters. the code is here below. (Python 2.7)
n = 1
all_odd_integers = 2*n+1
prime_number = 2 #cause 3 is the second prime
while prime_number < 1000: #a while loop to get to prime thousand
for i in range (2, (all_odd_integers-1)): #because I want to divide all_odd_integers by all numbers except 1 and itsself and nothing bigger, but bigger than 0
if all_odd_integers % i == 0:
n += 1
print "not a prime" #because, like, if a number can be divided without a reminder it's not a prime
else:
n = n+1
prime_number += 1
print "a prime" #because exactly the opposite of the if-clause, here there is a reminder so prime
if prime_number == 1000:
print "the thousandth prime is %d" (all_odd_integers)
Your code isn't working because you have an infinite while loop, since your for loop isn't even being executed. You almost have the approach right for calculating the primes however.
If you want to print out every prime number as your current code would if it worked, you can much more easily implement something like this :
counter = 1
prime = 3
while counter != 1000:
for x in range(2,prime):
if prime%x == 0:
break
else:
print(prime)
counter += 1
prime += 2
Alternatively, if you only want to print out the thousandth prime I'm sure there are a plethora of more efficient ways, but I would lean towards something like this for simplicity and decent efficiency:
from math import sqrt
counter = 1
prime = 1
while counter < 1000:
prime += 2
for x in range(2,int(sqrt(prime+1)) + 1):
if prime%x == 0:
break
else:
counter += 1
print (prime)
I think you're thinking about this too hard. There are some errors to your code, but really it can all be boiled down to:
counter = 1
n = 2
while True:
n += 1
if all(n % i for i in xrange(2, n)): counter += 1
if counter == 1000: break
print "the thousandth prime is {0}".format(n)
This loops through all numbers between 2 and itself to see if any of them return a 0 remainder when n is divided by them. If none do, it's a prime and counter gets ticked, if not then it goes on to the next number. Once it finds 1000 primes it breaks and prints the thousandth prime is 7919
Some of the things wrong with your code:
all_odd_integers never changes. So when you do for i in range(2, (all_odd_integers-1)) it will never run anything except for i in range(2, 2) which is 0 because range excludes the higher number. all_odd_integers = 2*n+1 is only run once, when all_odd_integers is defined, it doesn't change when n does.
Even if all_odd_integers did update, why would you multiply it by two? Wikipedia has a prime defined as:
A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
If n was 3 then all_odd_integers would be 7? Why would 3 need to be divided by 4-6?
Just a note: there is no need to check if prime_number is equal to 1000 at the end since that's why the code block broke.
What if you start with n=2 and prime_number = 3? that way you'll reach the for loop.
Like the other anwserers, the condition in the while loop never changes.
Look at your range() call:
range (2, (all_odd_integers-1))
When you call range, there is a start (2) and a stop (all_odd_integers-1).
range(1,5) generates: 1,2,3,4
Look at all_odd_integers:
all_odd_integers = 2*n+1
2*n+1 means 2*1+1 because n = 1 so 2*n+1 = 3 therefore you are calling range(2,2) which gives [] and then the loop is never executed at all.
EDIT: More things
This function gives you your odd integers.
def odd_integers():
odd_integers = []
for i in xrange(1001):
if i/2 != int(i/2);
odd_integers.append(i)
return odd_integers
Here's your new for:
for i in odd_integers():
The condition in your while loop is always true. prime_number doesn't ever change. Look again at your code
for i in range (2, (all_odd_integers-1)):
What is this supposed to do if n=1 and therefore all_odd_integers-1 = 2?
The code under this loop is never executed.
EDIT:
To loop over odd integers just do this:
for i in xrange(1,1000,2):

Project Euler #7 Python

I'm having trouble with my code. The question is:
"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 10 001st prime number?"
This is what it looks like:
div = 10001
i = 2
count = 0
prime = 0
now = []
while count < div:
for x in range (2,i+1):
if len(now) ==2:
break
elif i%x == 0:
now.append(x)
if len(now)==1:
prime = i
count += 1
now = []
i+=1
print(prime)
I have tried div up to 1000 and it seems to work fine(for div 1000 I receive 7919). However, when I try div = 10001 I get nothing, not even errors. If someone would help me out I would really appreciate it.
Thank you.
# 7 10001st prime
import itertools
def is_prime(n):
for i in range(2, n//2 + 1):
if n % i == 0:
return False
else:
continue
return True
p = 0
for x in itertools.count(1):
if is_prime(x):
if p == 10001:
print(x)
break
p += 1
Try this code:
prime_list = lambda x:[i for i in xrange(2, x+1) if all([i%x for x in xrange(2, int(i**0.5+1))])][10000]
print prime_list(120000)
Lambda in Python defines an anonymous function and xrange is similar to range, defining a range of integer numbers. The code uses list comprehension and goes through the numbers twice up to the square root of the final number (thus i**0.5). Each number gets eliminated if it is a multiple of the number that's in the range count. You are left with a list of prime numbers in order. So, you just have to print out the number with the right index.
With just some simple modifications (and simplifications) to your code, you can compute the number you're looking for in 1/3 of a second. First, we only check up to the square root as #Hashman suggests. Next, we only test and divide by odd numbers, dealing with 2 as a special case up front. Finally, we toss the whole now array length logic and simply take advantage of Python's break logic:
limit = 10001
i = 3
count = 1
prime = 2
while count < limit:
for x in range(3, int(i ** 0.5) + 1, 2):
if i % x == 0:
break
else: # no break
prime = i
count += 1
i += 2
print(prime)
As before, this gives us 7919 for a limit of 1000 and it gives us 104743 for a limit of 10001. But this still is not as fast as a sieve.
m=0
n=None
s=1
while s<=10001:
for i in range(1,m):
if m%i==0:n=i
if n==1:print(m,'is prime',s);s+=1
m+=1

Categories

Resources