isPrime Function for Python Language - python

So I was able to solve this problem with a little bit of help from the internet and this is what I got:
def isPrime(n):
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
But my question really is how to do it, but WHY. I understand that 1 is not considered a "prime" number even though it is, and I understand that if it divides by ANYTHING within the range it is automatically not a prime thus the return False statement. but my question is what role does the squar-rooting the "n" play here?
P.s. I am very inexperienced and have just been introduced to programming a month ago.

Of many prime number tests floating around the Internet, consider the following Python function:
def is_prime(n):
if n == 2 or n == 3: return True
if n < 2 or n%2 == 0: return False
if n < 9: return True
if n%3 == 0: return False
r = int(n**0.5)
# since all primes > 3 are of the form 6n ± 1
# start with f=5 (which is prime)
# and test f, f+2 for being prime
# then loop by 6.
f = 5
while f <= r:
print('\t',f)
if n % f == 0: return False
if n % (f+2) == 0: return False
f += 6
return True
Since all primes > 3 are of the form 6n ± 1, once we eliminate that n is:
not 2 or 3 (which are prime) and
not even (with n%2) and
not divisible by 3 (with n%3) then we can test every 6th n ± 1.
Consider the prime number 5003:
print is_prime(5003)
Prints:
5
11
17
23
29
35
41
47
53
59
65
True
The line r = int(n**0.5) evaluates to 70 (the square root of 5003 is 70.7318881411 and int() truncates this value)
Consider the next odd number (since all even numbers other than 2 are not prime) of 5005, same thing prints:
5
False
The limit is the square root since x*y == y*x The function only has to go 1 loop to find that 5005 is divisible by 5 and therefore not prime. Since 5 X 1001 == 1001 X 5 (and both are 5005), we do not need to go all the way to 1001 in the loop to know what we know at 5!
Now, let's look at the algorithm you have:
def isPrime(n):
for i in range(2, int(n**0.5)+1):
if n % i == 0:
return False
return True
There are two issues:
It does not test if n is less than 2, and there are no primes less than 2;
It tests every number between 2 and n**0.5 including all even and all odd numbers. Since every number greater than 2 that is divisible by 2 is not prime, we can speed it up a little by only testing odd numbers greater than 2.
So:
def isPrime2(n):
if n==2 or n==3: return True
if n%2==0 or n<2: return False
for i in range(3, int(n**0.5)+1, 2): # only odd numbers
if n%i==0:
return False
return True
OK -- that speeds it up by about 30% (I benchmarked it...)
The algorithm I used is_prime is about 2x times faster still, since only every 6th integer is looping through the loop. (Once again, I benchmarked it.)
Side note: x**0.5 is the square root:
>>> import math
>>> math.sqrt(100)==100**0.5
True
Side note 2: primality testing is an interesting problem in computer science.

With n**.5, you are not squaring n, but taking the square root.
Consider the number 20; the integer factors are 1, 2, 4, 5, 10, and 20. When you divide 20 by 2 and get 10, you know that it is also divisible by 10, without having to check. When you divide it by 4 and get 5, you know it is divisible by both 4 and 5, without having to check for 5.
After reaching this halfway point in the factors, you will have no more numbers to check which you haven't already recognized as factors earlier. Therefore, you only need to go halfway to see if something is prime, and this halfway point can be found by taking the number's square root.
Also, the reason 1 isn't a prime number is because prime numbers are defined as having 2 factors, 1 and itself. i.e 2 is 1*2, 3 is 1*3, 5 is 1*5. But 1 (1*1) only has 1 factor, itself. Therefore, it doesn't meet this definition.

The question was asked a bit ago, but I have a shorter solution for you
def isNotPrime(Number):
return 2 not in [Number,2**Number%Number]
The math operation will mostly return 2 if the number is a prime, instead of 2. But if 2 is the given number, it is appended to the list where we are looking into.
Examples:
2^5=32 32%5=2
2^7=128 128%7=2
2^11=2048 2048%11=2
Counter examples:
2^341%341=2, but 341==11*31
2^561%561=2, but 561==3*11*17
2^645%645=2, but 645==3*5*43
isNotPrime() reliably returns True if Number is not prime though.

No floating point operations are done below. This is faster and will tolerate higher arguments. The reason you must go only to the square-root is that if a number has a factor larger than its square root, it also has a factor smaller than it.
def is_prime(n):
""""pre-condition: n is a nonnegative integer
post-condition: return True if n is prime and False otherwise."""
if n < 2:
return False;
if n % 2 == 0:
return n == 2 # return False
k = 3
while k*k <= n:
if n % k == 0:
return False
k += 2
return True

This method will be slower than the the recursive and enumerative methods here, but uses Wilson's theorem, and is just a single line:
from math import factorial
def is_prime(x):
return factorial(x - 1) % x == x - 1

Finding the square root of the number is for efficiency. eg. if I am trying to find the factors of 36, the highest number that can be multiplied by itself to form 36 is 6. 7*7 = 49.
therefore every factor of 36 has to be multiplied by 6 or a lesser number.

def is_prime(x):
if x < 2:
return False
elif x == 2:
return True
for n in range(2, x):
if x % n ==0:
return False
return True

This is my method:
import math
def isPrime(n):
'Returns True if n is prime, False if n is not prime. Will not work if n is 0 or 1'
# Make sure n is a positive integer
n = abs(int(n))
# Case 1: the number is 2 (prime)
if n == 2: return True
# Case 2: the number is even (not prime)
if n % 2 == 0: return False
# Case 3: the number is odd (could be prime or not)
# Check odd numbers less than the square root for possible factors
r = math.sqrt(n)
x = 3
while x <= r:
if n % x == 0: return False # A factor was found, so number is not prime
x += 2 # Increment to the next odd number
# No factors found, so number is prime
return True
To answer the original question, n**0.5 is the same as the square of root of n. You can stop checking for factors after this number because a composite number will always have a factor less than or equal to its square root. This is faster than say just checking all of the factors between 2 and n for every n, because we check fewer numbers, which saves more time as n grows.

def is_prime(x):
if x < 2:
return False
for n in range(2, (x) - 1):
if x % n == 0:
return False
return True

I don't know if I am late but I will leave this here to help someone in future.
We use the square root of (n) i.e int(n**0.5) to reduce the range of numbers your program will be forced to calculate.
For example, we can do a trial division to test the primality of 100. Let's look at all the divisors of 100:
2, 4, 5, 10, 20, 25, 50
Here we see that the largest factor is 100/2 = 50. This is true for all n: all divisors are less than or equal to n/2. If we take a closer look at the divisors, we will see that some of them are redundant. If we write the list differently:
100 = 2 × 50 = 4 × 25 = 5 × 20 = 10 × 10 = 20 × 5 = 25 × 4 = 50 × 2
the redundancy becomes obvious. Once we reach 10, which is √100, the divisors just flip around and repeat. Therefore, we can further eliminate testing divisors greater than √n.
Take another number like 16.
Its divisors are, 2,4,8
16 = 2 * 8, 4 * 4, 8 * 2.
You can note that after reaching 4, which is the square root of 16, we repeated 8 * 2 which we had already done as 2*8. This pattern is true for all numbers.
To avoid repeating ourselves, we thus test for primality up to the square root of a number n.
So we convert the square root to int because we do not want a range with floating numbers.
Read the primality test on wikipedia for more info.

def isPrime(num,div=2):
if(num==div):
return True
elif(num % div == 0):
return False
else:
return isPrime(num,div+1)
==============================================
EDITED
def is_prime(num, div = 2):
if num == div: return True
elif num % div == 0: return False
elif num == 1: return False
else: return is_prime(num, div + 1)

isPrime=lambda x: all(x % i != 0 for i in range(int(x**0.5)+1)[2:])
and here goes how to use it
isPrime(2) == False
isPrime(5) == True
isPrime(7) == True
To find all primes you might use:
filter(isPrime, range(4000)[2:])[:5]
=> [2, 3, 5, 7, 11]
Note that 5, in this case, denotes number of prime numbers to be found and 4000 max range of where primes will be looked for.

Every code you write should be efficient.For a beginner like you the easiest way is to check the divisibility of the number 'n' from 2 to (n-1). This takes a lot of time when you consider very big numbers. The square root method helps us make the code faster by less number of comparisons. Read about complexities in Design and Analysis of Algorithms.

int(n**0.5) is the floor value of sqrt(n) which you confused with power 2 of n (n**2). If n is not prime, there must be two numbers 1 < i <= j < n such that: i * j = n.
Now, since sqrt(n) * sqrt(n) = n assuming one of i,j is bigger than (or equals to) sqrt(n) - it means that the other one has to be smaller than (or equals to) sqrt(n).
Since that is the case, it's good enough to iterate the integer numbers in the range [2, sqrt(n)]. And that's exactly what the code that was posted is doing.
If you want to come out as a real smartass, use the following one-liner function:
import re
def is_prime(n):
return not re.match(r'^1?$|^(11+?)\1+$',n*'1')
An explanation for the "magic regex" can be found here

Implemented a pseudocode (https://en.wikipedia.org/wiki/Primality_test) in python, hope this help.
# original pseudocode https://en.wikipedia.org/wiki/Primality_test
def isPrime(n):
# Corner Cases
if (n<= 1): return False
elif (n<= 3): return True
elif (n%2 == 0 or n%3 == 0): return False
i = 5
while i*i<=n:
if (n%i==0 or n%(i+2)==0): return False
i += 6
return True;
%timeit isPrime(800)

This is my np way:
def is_prime(x):
if x < 4:
return True
if all([(x > 2), (x % 2 == 0)]):
return False
else:
return np.array([*map(lambda y: ((x % y) == 0).sum(), np.arange(1, x + 1))]).sum() == 2
Here's the performance:
%timeit is_prime(2)
%timeit is_prime(int(1e3))
%timeit is_prime(5003)
10000 loops, best of 3: 31.1 µs per loop
10000 loops, best of 3: 33 µs per loop
10 loops, best of 3: 74.2 ms per loop

def is_prime(n):
n=abs(n)
if n<2: #Numbers less than 2 are not prime numbers
return "False"
elif n==2: #2 is a prime number
return "True"
else:
for i in range(2,n): # Highlights range numbers that can't be a factor of prime number n.
if n%i==0:
return "False" #if any of these numbers are factors of n, n is not a prime number
return "True" # This is to affirm that n is indeed a prime number after passing all three tests

It was an exercise in codecademy and that's how i passed it below...
def is_prime(x):
# If number(x) is evenly divided by following dividers then number(x) is not prime
divider = [2, 3, 5, 7]
# An empty list to be able to check whether number(x) is evenly divided:
remainder = []
# exceptions for numbers 1,2,3,5,7:
if x < 2:
return False
if x in divider:
return True
else:
for nums in divider:
remainder.append(x % nums)
if 0 in remainder:
return False
else:
return True

def is_prime(n):
if (n==2 or n==3): return True
if(n<=1 or n%2==0 or n%3==0 ): return False
for i in range(6,int((n**0.5)) + 2,6):
if(n%(i-1)==0 or n%(i+1)==0):
return False
return True

This is the answer to that website.
def is_Prime(n):
if n <= 3:
return n > 1
if n % 2 == 0 or n % 3 == 0:
return False
i = 5
while i ** 2 <= n:
if n % i == 0 or n % (i + 2) == 0:
return False
i += 6
return True
isPrime=list()
c=-1
for i in range(0,1000001):
c=c+1
isPrime.append(c)
if is_Prime(isPrime[i])==True:
isPrime[i]=True
else:
isPrime[i]=False

This entire solution is based on factors. A natural number which has exactly two factors, i.e. 1 and the number itself, is a prime number. In simple words, if a number is only divisible by 1 and itself, then it is a prime number. Every prime number is an odd number except number 2.
def isprime(x):
factors=[]
if x < 2:
return False
for i in range(1,x+1):
if (x % i == 0):
factors.append(i)
return True if len(factors) <=2 else False

Remember kids order of operations is important.
Doing it like this eliminates useless branches that costs performance and checks special rare cases only when necessary. there is no need to check if n == 2 unless n is odd. And there is no need to check if n <= 1 unless n is not divisible by any positive numbers other than itself and 1 because it's a rare special case. Also checking if not n%5 is slower, atleast in python. That's why I stopped in 3.
from math import sqrt
def is_prime(n):
if not n%2: return n==2
if not n%3: return n==3
for i in range(5,int(sqrt(n))+1,2):
if not n%i: return False
return n>1
This is even faster solution, which doesn't check numbers that are multipliers of 2 and 3 (in the loop) instead of 2 only. Btw, I stored int(sqrt(n)) to prevent the while loop from calculating it every iteration.
def is_prime(n):
if not n&1: return n==2
if not n%3: return n==3
i,r=5,int(sqrt(n))
while i<=r:
if not n%i or not n%(i+2): return False
i+=6
return n>1

Pretty simple!
def prime(x):
if x == 1:
return False
else:
for a in range(2,x):
if x % a == 0:
return False
return True

def fun(N):#prime test
if N>1 :
for _ in xrange(5):
Num=randint(1,N-1)
if pow(Num,N-1,N)!=1:
return False
return True
return False
True if the number is prime otherwise false

The number 1 is a special case which is considered neither prime nor composite.
For more info visit : http://mathworld.wolfram.com/PrimeNumber.html
And,
(n**0.5) --> This will give us the "square root" of 'n'. As it is "n raised to the power 0.5 or 1/2"
And WHY do we do that,
Take for example the number 400:
We can represent it in the form a*b
1*400 = 400
2*200 = 400
4*100 = 400
5*80 = 400
8*50 = 400
10*40 = 400
16*25 = 400
20*20 = 400
25*16 = 400
40*10 = 400
50*8 = 400
80*5 = 400
100*4 = 400
200*2 = 400
400*1 = 400
Square root of 400 is 20:
and we can see that we only need to check the divisibility till 20 because, as 'a' reaches 20 'b' starts decreasing...
So, ultimately we are checking divisibility with the numbers less than the square root.

I have a new solution which I think might be faster than any of the mentioned
Function in Python
It's based on the idea that:
N/D = R
for any arbitrary number N, the least possible number to divide N (if not prime) is D=2 and the corresponding result R is (N/2) (highest).
As D goes bigger the result R gets smaller ex: divide by D = 3 results R = (N/3)
so when we are checking if N is divisible by D we are also checking if it's divisible by R
so as D goes bigger and R goes smaller till (D == R == square root(N))
then we only need to check numbers from 2 to sqrt(N)
another tip to save time, we only need to check the odd numbers as it the number is divisible by any even number it will also be divisible by 2.
so the sequence will be 3,5,7,9,......,sqrt(N).
import math
def IsPrime (n):
if (n <= 1 or n % 2 == 0):return False
if n == 2:return True
for i in range(3,int(math.sqrt(n))+1,2):
if (n % i) == 0:
return False
return True

(https://www.youtube.com/watch?v=Vxw1b8f_yts&t=3384s)
Avinash Jain
for i in range(2,5003):
j = 2
c = 0
while j < i:
if i % j == 0:
c = 1
j = j + 1
else:
j = j + 1
if c == 0:
print(str(i) + ' is a prime number')
else:
c = 0

def is_prime(x):
if x<2:
return False
elif x == 2:
return True
else:
for n in range(2, x):
if x%n==0:
return False
return True

Srsly guys... Why so many lines of code for a simple method like this? Here's my solution:
def isPrime(a):
div = a - 1
res = True
while(div > 1):
if a % div == 0:
res = False
div = div - 1
return res

Related

Goldbach Conjecture Verify up to N in Python

I seem to have created an infinite loop in my python code. My aim was to create a function 'check' which uses my previous 'goldbach' function to confirm that every even number greater than 4 and up to the inputted N comply with the Goldbach Conjecture (a pretty pointless procedure, I know, but it's for my assignment). I know that my 'goldbach' function is working well and produces a pair of primes that sum to N for 'good' inputs and (0,0) for 'bad' inputs. I want my check function to return True for all even inputs greater than 4 (as these comply with the conjecture), and False for any odd inputs. However, my code won't run when I try my check function in the console so something has gone wrong - any ideas what it is?
def goldbach(N):
x, y = 0, 0
result = 0
if N % 2 == 0:
prime = odd_primes(N)
while result != N:
for i in range(len(prime)):
if result == N: break
x = prime[i]
for j in range(len(prime)):
y = prime[j]
result = x + y
if result == N: break
return x, y
def check(N):
for n in range(4, N+1):
if n % 2 ==0:
g = goldbach(n)
if g == (0,0):
return False
else:
return True
You're returning immediately after checking the first item in the range. You need to return False as soon as you encounter an item that doesn't match expectations, and return True at the end if all of them match expectations.
If you only want to look at even numbers, use a stride of 2 in the range() function rather than testing each number to see if it's even or odd.
def check(N):
for n in range(4, N+1, 2):
if goldbach(n) == (0, 0):
return False
return True
You don't need the while loop in goldbach(). The two for loops test all combinations of primes. If they don't find a matching pair, there's no reason to restart them.
You can also simplify and optimize your loops. The inner loop only needs to test primes starting from x, because pairs of primes where y < x would have already been tested in an earlier iteration of x.
def goldbach(N):
if N % 2 == 0:
prime = odd_primes(N)
for i, x in enumerate(prime):
for y in prime[i:]:
if x + y == N:
return x, y
return 0, 0
However, I think your code should still work, which suggests that the problem is actually that odd_primes() isn't returning all primes up to N.
I just created a replacement for your function odd_primes(N), to return a list of all the primes less than or equal to N (having 2 in the there doesn't seem to make a difference). Your check() function seems to check all integers between 4 and N inclusive, and return False if it finds something for which no Goldbach sum was found. However, as somebody else pointed out, it also immediately returns True once it finds a pair. So what happens when you run check() is that starts with the number 4, finds that its Goldbach pair is (2,2), then immediately quits the function by returning True, ignoring any other values between 4 and N.
When I replace the return True with a print statement and just add a `return True after the entire loop:
def check(N):
for n in range(4, N+1):
if n % 2 ==0:
g = goldbach(n)
if g == (0,0):
print("No sum found for %d !" % n)
return False
else:
print("%d is equal to %d + %d" % (n, g[0], g[1]))
return True
and then run check(20) for example, I get:
4 is equal to 2 + 2
6 is equal to 3 + 3
8 is equal to 3 + 5
10 is equal to 3 + 7
12 is equal to 5 + 7
14 is equal to 3 + 11
16 is equal to 3 + 13
18 is equal to 5 + 13
20 is equal to 3 + 17
By the way, if you just want to know whether a given even number can be written as the sum of two primes but you don't care what the actual pair of primes is, you could do something like this:
def goldbach(N):
if N % 2 == 0:
primes = odd_primes(N)
# Generate a list of all the i+j sums where j >= i (skipping
# most duplicates this way), and see if N is among the sums.
sums = [i + j for i in primes for j in primes[primes.index(i):]]
return(N in sums)
else:
print("N must be even.")
return(False)

If a number is a Prime Number?

def isPrime(n):
if n == 1:
return False
else:
for i in range(2,n):
if n%i == 0:
return False
return True
I'd like to know why this code omits two when saying if a number isPrime and how do I fix it if I should make the value of n be 2.
range(2,2) is empty.
you can see it by doing
for i in range(2,2):
print(i)
Im new to python. About two days lol.
But i think i can see what the problem is.
The range(a, b) function counts to the length "b-a"
because thats what a range is(highest - smallest)
So when you're using the range() function write it out this way:
def isPrime(n):
if n == 1:
return False
else:
for i in range(1,n):
if n%i == 0:
return False
return True
print(isPrime(n))
It omits 2 because range(2,2) is empty, like the other answers have stated. However, for n=2 you WANT the range to be empty, because you never want to include 1 (every positive integer is divisible by 1), and 2 is divisible by 2. In general, you want to use range(2, n) because n is divisible by n.
Another problem here is that you return True within the for loop; this means that on the first pass through the loop for n≥3, if n is odd the function will return True. The solution to this is just to knock the return True statement back a level of indentation. That way, if the range is empty, or only after checking if n is divisible by every number from 2 to n-1 inclusive, you return True. It should look something like this:
def isPrime(n):
if n == 1:
return False
else:
for i in range(2,n):
if n%i == 0:
return False
return True
It omits 2 because of the range function:
print(list(range(2,2)))
[]
In your code, if you want to include n, you should use range(2,n+1)
for this specific issue, you could do something like:
def isPrime(n):
if n == 1:
return False
elif n == 2:
return False
else:
prime = True
for i in range(2,n):
if n%i == 0:
prime = False
break
return prime
print(isPrime(6))
The elif catches the special case where n == 2. Additionally, I inserted an extra variable which is set to False when the modulo becomes 0 (thus, the variable is not a prime number)
The break makes sure that the check is stopped once a remainder becomes 0, and it is returned whether your variable is prime or not.
I checked it, and got to the following results:
False
for input = 6
and
True
for input = 11
"The simplest primality test is trial division: Given an input number n, check whether any prime integer m from 2 to √n evenly divides n (the division leaves no remainder). If n is divisible by any m then n is composite, otherwise it is prime."
Wikipedia article on primality test, Look at the simple test to understand why this works.
It looks like you keep dividing numbers to see if any number up to that number divides it. You will realize that for a given n, the largest number that can divide n is some m, such that 2 * m = n. So firstly, indexing all the way up to n is checking each case twice. Example:
8 % 1 == 8?
8 % 2 == 0? -> 8 / 2 = 4
8 % 3 == 0?
8 % 4 == 0? -> 8 / 4 = 2
8 % 5 == 0?
8 % 6 == 0?
8 % 7 == 0?
To mitigate these duplicate checks: You square i, and only check divisors (i) no greater √n. In this case, n=8, We stop at i = 3, because then we just swap the divisors order, and check the same cases over again.
Also note: We will start our loop at n = 5, because we check the base cases n = 1, 2 or 3? and we know 4 is not prime:
Output:
1 is not prime
2 is prime
3 is prime
4 is not prime
5 is prime
6 is not prime
7 is prime
8 is not prime
9 is not prime
Code:
# Via Trivial division
def isPrime(n):
# False by definition
if n <= 1:
return False
# Consider 2 and 3 base cases
# for THIS method of detecting
# prime numbers (trivial division)
elif n <= 3:
return True
# Check that 2 or 3 divides n
elif n % 2 == 0 or n % 3 == 0:
return False
i = 5
while (i * i) <= n:
if n % i == 0 or n % (i + 2):
return False
i = i + 6
return True
#--------------------------------------
j = 1
while j < 10:
if (isPrime(j)):
print(str(j) + " is prime")
else:
print(str(j) + " is not prime")
j = j + 1

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

Project Euler Q #3 Python

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

Finding Primes Different Approach

I am trying to make a program that finds primes numbers for a public-key cryptography system. I know that a prime number is a positive integer that has no positive divisors other than 1 and itself. I want to use an approach that that takes all integers from 2 to sqrt(n), to tell if it divides n or not.
I have to take a "brute force" approach that takes in an integer input seed and returns the lowest prime number; prime number >= seed.
Some examples of what I want is :
>>> prime_func(100)
101
>>> prime_func(1000)
1009
>>>prime_func(7)
7
>>>prime_func(3)
5
What I have so far is:
def prime_func(number):
START = 2
END = (number**0.5) + 1
for i in range(START, END):
if number % i == 0:
return('Composite')
else:
return number
For the return ('Composite') part, I want it to instead return the closest prime number after that.
Try the following code:
def prime_func(number):
number = int(number)
START = 2
END = int((number**0.5)) + 1
if number == 2:
return 1
if number == 1:
return 0
while True:
flag = True
for i in range(START, END):
if number % i == 0:
flag = False
break
if flag:
return number
else:
number += 1
if __name__ == '__main__':
num = int(input())
print(prime_func(num))
Input: 100
Output: 101
Input: 1000
Output: 1009
This can be achieved using a Sieve of Eratosthenes.
Code:
def primes_sieve(limit):
a = [True] * limit # Initialize the primality list
a[0] = a[1] = False
for (i, isprime) in enumerate(a):
if isprime:
yield i
for n in range(i*i, limit, i): # Mark factors non-prime
a[n] = False
for value in primes_sieve(32):
print(value)
Output:
2
3
5
7
11
13
17
19
23
29
31
See This Post.

Categories

Resources