Given an integer n, the function legendre_n should return the number of prime numbers between n^2 and (n+1)^2.
This is the code I wrote:
def legendre_n(n):
"""Returns the number of primes between n**2 and (n+1)**2"""
count = 0
for i in range(n**2, ((n+1)**2)):
if i%2 != 0:
count += 1
return count
print(legendre_n(12)) = > 5 but I'm getting 12
print(legendre_n(3)) => 2 but I'm getting 4
After testing on python tutor, I found out that the condition I set (i%2 != 0) only filters out odd numbers. However, not all odd numbers are prime numbers. I understand that prime numbers should only be divisible by 1 and the number itself, but I'm stucked at setting the correct condition.
This should do the trick:
def legendre_n(n):
"""Returns the number of primes between n**2 and (n+1)**2"""
count = 0
for num in range(n**2, ((n+1)**2)):
if num > 1:
for i in range(2, num):
if (num % i) == 0:
break
else:
count = num
return count
you want to check either your num is devidable with any other number between 2 and itself (modulo calculation). If not, it is a prime number.
There is no known "fast" computation to determining if a number is prime. The only known methods involve loops of checks (see some of the other answers). This makes prime factorization a key component in cryptography.
The long story short, is that you must define a function like the ones mentioned above, or you must import one. For example, sympy.isprime() is a highly optimized function that probably runs much faster. Of course, if you are going to import the amazing number theory package, why not just do:
import sympy
def legendre_n(n):
count = 0
for _ in sympy.primerange(n**2,(n+1)**2+1):
count += 1
return count
You only need is make a identifier of prime numbers.
you can try this:
def isprime(n):
for i in range(2,n):
if(n%i)==0:return False
return True
def legendre_n(n):
"""Returns the number of primes between n**2 and (n+1)**2"""
count = 0
for i in range(n**2, ((n+1)**2)):
if isprime(i):
count += 1
return count
Related
I want to find all the PRIME numbers up to the given number, and add them to their lists respectively.
The number '100', has 25 primes, whereas I get 1060. What am I doing wrong?
!pip install sympy
import sympy
def count_primes(num):
primes = 0
nonprimes = 0
for x in range(0, num):
if sympy.isprime(x) == True:
primes = primes + x
else:
nonprimes = nonprimes + x
return primes
It seems like your are mixing the listing of primes and the counting.
You can either add all the primes and nonprimes to a list by defining
primes, nonprimes = [],[]
and keep everything else the same. This will just return the list of primes.
If you want to count the primes from 0 to 100, you can change the code in your if and else statement to
primes+=1
and
nonprimes +=1
and you will return the number of primes between 0 and 100.
instead of increasing of "primes" value by 1 you add "x" in "primes" when number is prime
You could this sympy.primerange() function to get a list of all prime numbers and use len() to get total number of primes for that number
def count_primes(num):
primes = list(sympy.primerange(0, num))
length = len(primes)
return length
print(count_primes(100)) #25
The problem lies within this:
if sympy.isprime(x) == True:
primes = primes + x
else:
nonprimes = nonprimes + x
Above, when you are doing primes = primes + x what you are saying is that you want to add the value of the x (a prime number) to the variable primes.
Thus what is happening, when you use 100 as your num your function will return 1060, as this is the sum of all the primes up to 100.
First, if you want to know the total amount of prime numbers up to a certain number, you can use the following:
#define a variable to track the total number of primes
primeTotal = 0
#using the if statement from before
if sympy.isprime(x) == True:
primeTotal += 1
What this does now, is for every instance of a prime number, you will add 1 to the count of prime numbers.
To create a list of prime numbers, you must first define a list, and then add the prime numbers to that list. Again, using the if statement from before:
#defining the list
primeNums = []
if sympy.isprime(x) == True:
primeNums.append(x)
Now what is happening is, for every instance of a prime number x (the prime number) is being added (appended) to the list primeNums. This should solve both your problems.
The final bit of code will look something like this:
import sympy
def count_primes(num):
primesTotal = 0
primeNums = []
for x in range(0, num):
if sympy.isprime(x) == True:
primesTotal += 1
primeNums.append(x)
return primesTotal, primeNums
print(primesTotal, primeNums)
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.
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.
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
I've tried with several different methods to get the 10001 prime number.
def isPrime(value):
if ((2**value)-2)%value==0:
return True
def nthPrime(n):
count = 0
value = 1
while count < n:
value += 1
if isPrime(value):
count += 1
return value
When 10001 is the argument this returns 103903. When I'm expecting 104743.
I've tried:
primes = []
for i in range(2,105000):
if ((2**i) - 2) % i == 0:
primes.append(i)
print primes[10001] ---> 103903
I believe your prime sieve is wrong. Try using an isPrime function that takes that number mod each lesser prime. If any of these are 0 then the number is composite (not prime). To the best of my knowledge there is no single comparison that will tell you if a number is prime, as your isPrime function assumes.
Is this for Project Euler? It does seem familiar to me.
Your isPrime function is wrong, like TEOUltimus said, there is no one way to tell if a number is prime.
Simple Prime Generator in Python
This pretty much answers your question i guess.
You can make a function to generate primes, this might be slow but it will work.
Here's my function to do so :
def PrimesSieve(limit):
np=set()
p=[2]
for i in xrange(1,limit+1,2):
if i == 1: continue
if {i} & np: continue
beg=2 if i % 2 == 0 else 0
for j in xrange(beg,int(limit)+1,i):
np.add(j)
p.append(i)
return p