I apologize in advance if this is a duplicate question - my search for python and modulus ran up to 8 pages of questions and that combined with my relatively little coding experience made it somewhat difficult for me to check thoroughly to see if there was anything extremely similar out there.
While trying to solve a Project Euler question, I wrote a function for testing whether or not a number was a prime number:
import math
def isprime(n):
if n % 1 != 0:
return(False)
else:
for j in range(2, math.ceil(math.sqrt(n)) + 1):
if n % j == 0:
return(False)
else:
return(True)
break
This works pretty well with small numbers, but with very large numbers that definitely aren't prime (e.g. I put in isprime(1012321312412431434334545555) and the function gives me a value of True). Why is this the case?
EDIT: as pointed out by roippi and confirmed by my further investigations, this function actually does not work for a lot of smaller odd composite numbers. I'm trying to figure out why that doesn't work for now.
I believe your problem is that the return is in the wrong place. Your code currently only loops through the 2, and any odd number is obviously not divisible by 2. So, it goes into the if n%j==0, returns True, and since a return breaks out of the loop, stops going. So, any odd number will return True.
Instead, try:
def isprime(n):
if n % 1 != 0:
return True
else:
for j in range(2, math.ceil(math.sqrt(n))):
if n % j != 0:
return False
return True
I think that works.
EDIT: No, it actually doesn't. Here, I'll post a different prime checker:
def isprime(n):
'''check if integer n is a prime'''
n = abs(int(n))
if n < 2:
return False
if n == 2:
return True
if not n & 1:
return False
for x in range(3, int(n**0.5)+1, 2):
if n % x == 0:
return False
return True
First of all, n % 1 == 0 will always return true for integers, because this tests if n is divisible by 1. So this is a bit of a nonsical test. If you want to check for odd/even numbers, use n % 2.
It does check for decimals, but in that case I think it's better to throw an error.
A better algorithm to test for prime is something like this:
def isPrime(n):
if n < 2:
return False
if n < 4:
return True
for x in range(2,ceil(sqrt(n)) + 1):
if (n % x == 0):
return False
return True
Related
def is_prime(x):
for i in range(2,x):
if (x % i) == 0:
return False
else:
return True
print(is_prime(9))
this is my function to find the prime number, i am not sure why its always return True for 9, any helps and explanation? Thanks
To understand why this is happening, take a look at what happens when 9 is passed into is_prime:
We enter the for loop, and set the initial value of i to be 2. Then, 9 % 2 = 1, not 0, so the if condition fails, and we go to the else condition, which then immediately returns True: But this isn't the definition of primality. We need that 9 is not divisible by any number smaller than it (apart from 1), not that it's not divisible by a single number. So, we can only return True once we've checked all the numbers in the range, like this:
def is_prime(x):
for i in range(2,x):
if (x % i) == 0:
return False
return True
Your code should now return the correct result for 9 (and, given infinite time, any natural number greater than 1).
A couple of things to think about: Do you need to check every number in range(2, x)? Perhaps you could look at what happens past the square root of x? Also, you might want to check if the number is less than 2 (i.e: 1, 0, -1, ...), because currently, your code will not give the correct result for these numbers. If you're interested also, the Sieve of Eratosthenes is a better algorithm than trial division for finding primes, which you might want to take a look at further down the line.
Because 9%2 is 1, and that is True
Here is how I fixed your code
def is_prime(x):
for i in range(2,x):
if (x % i) == 0:
return False
print(is_prime(9))
HOWEVER, this doesn't take into account of 0 and 1. So here is a more correct one
def is_prime(x):
if(x==0 or x==1):
return False
for i in range(2,x-1):
if (x % i) == 0:
return False
else:
return True
print(is_prime(9))
I have this code:
def has_divisors(n, i=2):
"""
Check if a number is prime or not
:param n: Number to check
:param i: Increasing value that tries to divide
:return: True if prime, False if not
"""
if n <= 1:
return False
if i + 1 == n:
return True
if n <= 2 and n > 0:
return True
if n % i == 0:
return False
return has_divisors(n, i + 1)
Which tell if a number is prime or not, problem is that it can check if a number is prime up to +- 1500 after that it enters into maximum recursion depth error. Does anyone has any idea how to make this code more efficient (I don't want completely different code, yes I know recursion is not a good idea for this function but I have to use it)
Thank you!
I actually made it more efficient by just adding one condition:
def has_divisors(n, i=2):
"""
Check if a number is prime or not
:param n: Number to check
:param i: Increasing value that tries to divide
:return: True if prime, False if not
"""
if n <= 1:
return False
if i == n:
return True
if n <= 2 and n > 0:
return True
if i * i > n:
return True
if n % i == 0:
return False
return has_divisors(n, i + 1)
Thanks to everyone who tried to help.
Modifying function from How do I find a prime number using recursion in Python
This should have a maximum recursion dept > 1M
Two improvements:
only goes to sqrt(N), and only checks odd numbers.
def has_divisors(N, i=3):
if N <= 2:
return False
elif N % 2 == 0: # even
return True
elif i * i > N: # tried all divisors to sqrt,
# must be prime
return False
elif (N % i) == 0: # i is a divisor
return True
else: # recursively try the next ( odd) divisor
return has_divisors(N, i + 2)
You don't need to do basic disqualifying tests on every recursion, so to make it more efficient, as you requested, I'd cast it like:
def has_no_divisors(n):
if n <= 2 or n % 2 == 0:
return n == 2
def has_no_divisors_recursive(n, i=3):
if i * i > n:
return True
if n % i == 0:
return False
return has_no_divisors_recursive(n, i + 2)
return has_no_divisors_recursive(n)
By treating 2 as a special case and just test dividing odd numbers, this should also have twice the performance (and half the stack usage) of your revised code.
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'm really trying to improve my math/coding/problem solving skills by working through the Project Euler problems, and I'm a little stuck on question three. The question is "The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 600851475143 ?"
And here's my code thus far
import math
def isPrime(n):
if n > 1:
for i in range(2, n):
if n % i == 0:
return False
else:
return True
else:
return False
def highFactor(m):
factors = []
for i in range(2, int(math.sqrt(m))):
if isPrime(i):
if m % i == 0:
factors.append(i)
print max(factors)
highFactor(13195)
So this obviously was testing on the example they gave since I already know the answer should be 29, but when I run the code it gives me 91. What did I do wrong?
Two issues:
(1) Your isPrime function returns True on the first iteration of the loop. You instead want to finish looping and then return True if you survive the entire loop without ever returning false.
(2) It's possible that an algorithm will have multiple copies of the same prime factor (ie 8 = 2*2*2). You would be better off setting m = m/i and restarting the loop every time. Also, you probably want sqrt(m)+1, since the range function excludes the upper limit.
As mentioned in the comments, your function returns True too early - e.g. if a number is not divisble by 2, it does not mean it will not be divisible by any later number in the range(2, n) - consider 51 = 3 * 17 as a counter-example.
Here is the correct version of your algorithm:
def isPrime(n):
if n > 1:
for i in range(2, n):
if n % i == 0:
return False
return True
else: # if we have a negative number or 0
return False
As others mentioned, there is a faster way to check whether a number is prime; now your function has complexity of O(n), since you check for all numbers up to n; by observation that n = sqrt(n) * sqrt(n) it is enough to check until sqrt(n) + 1
def isPrime(n):
if n > 1:
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
else:
return False
As Austin commented isPrime returns true too early. By moving return True outside of the for loop your function will check each number in range(2, n) before confirming that the number is prime.
Say you were to do isPrime(13) which should return True
On the first pass of the for loop if n % i == 0 would be if 13 % 2 == 0 which is False. Because of the else: return True in the for loop the function will return True and terminate.
To solve the issue you could write isPrime() like:
def isPrime(n):
if n > 1:
for i in range(2, n):
if n % i == 0:
return False
return True
else:
return False
This was the question our teacher gave us:
"One way to determine whether or not a number is a prime number is as follows:
if the number < 2, then return False
if the number is 2, then return True
for each value of i, where i >=2 and i < number:
if i divides the number evenly, then return False
return True"
I've managed to work through most of it, but was stuck when it said 'for each value of i, where i >=2 and i < number:'
how do I write this in code?
if number < 2:
return False
if number == 2:
return True
?????????
if i%2 == 0:
return False
return True
Yo need a loop to check all numbers from 2 to one less than the number being checked. There are better ways to do it (such as only checking up to the square root of the number) but a simplistic algorithm would be:
def isPrime (n):
if n < 2:
return False
for x in range (2, n):
if n % x == 0:
return False
return True
So, in terms of what you need to add to your code:
a loop iterating some variable from two up to one less than the number.
checking modulo with that variable rather than the hard-coded 2.
You will need to start a loop from 2 to the number
for i in range(2,number)
if number%i == 0:
return false
def isprime(num):
#this is the part you are missing
for divider in range(2,num):
if num%divider == 0:
return False
#end of missing part
return not num%2 == 0 or num==2 or num==0
for i in range(0,200):
if isprime(i): print i, isprime(i)