67

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 square-rooting the "n" play here?

P.s. I am very inexperienced and have just been introduced to programming a month ago.

whytheq
  • 34,466
  • 65
  • 172
  • 267
  • 10
    This is a little tangential, but [this explains why 1 is not prime](http://primes.utm.edu/notes/faq/one.html) – munk Mar 08 '13 at 02:14
  • 3
    are all factors of numbers less than the square root of the number itself? ...so no point checking numbers above that value to see if they are factors. – whytheq Apr 25 '14 at 14:35
  • related: [What is the best algorithm for checking if a number is prime?](http://stackoverflow.com/q/1801391/4279) – jfs Sep 21 '15 at 18:07
  • 1
    @whytheq: No, for example 28331 has a factor higher than its square root (sqrt(28331) is approximately 168.3, while the this number has factor of 691). However for every factor higher than the square root of the number, there exists a related integer lower than the square root (in example case 41). There's no need to check for factors above square root (as it would have already found the related integer and hence determine the number is not prime). The square root itself needs to be checked as that's the special case when the tested number is a 2nd power there are two equal factors. – desowin Jan 30 '18 at 13:36
  • 3
    To answer the question in the title: use `from sympy import isprime`. To answer the question in bold: p isn't prime <=> p = a*b with a,b > 1, and at least one of the factors must be <= sqrt(n) = n**0.5 (since b = n/a, so if a is larger, b is smaller). So it's enough to search for a factor up to square root of n. And actually one should first check whether n is even and then only odd factors 3, 5, 7, ... (could be restricted to primes but that makes it more complicated). – Max Mar 13 '20 at 22:16
  • by the way your solution has bug - it fails to exclude 1 from list of primes – Drako Jul 22 '20 at 05:47
  • Your question - " what role does the squar-rooting the "n" play here? " - The role of the upper bound of the integers to try to see if this number is a prime - as @whytheq says tacitly. Think of the number 83. 9 * 9 = 81 so Sqrt(83) is 9.11. When you divide 83 by 9, the result is 9.22. If you divide 83 by the next number 10, the result - 8.3 but you already tried dividing by 9,8 so no point trying to divide by 10, 11 etc. – Sumit S Jun 26 '23 at 17:26

30 Answers30

113

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:

  1. not 2 or 3 (which are prime) and
  2. not even (with n%2) and
  3. 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:

  1. It does not test if n is less than 2, and there are no primes less than 2;
  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.

dawg
  • 98,345
  • 23
  • 131
  • 206
  • 1
    @minitech: How does this 'not answer the question at all'? – dawg Mar 08 '13 at 03:35
  • Before you edited it, it gave an alternative solution for prime testing — better, but the question wasn’t whether there was a better one. Your edits *do* answer the question and augment it with a better solution, so I withdrew my downvote. And added an upvote and such. Thanks for notifying ;) – Ry- Mar 08 '13 at 04:13
  • 3
    All prime numbers, other than 2 & 3, are of the form `6n+/-1`. All composite numbers have prime factors. This algorithm leverages those two facts to reduce the number of checks per number. Could add that to the answer. – elssar Mar 08 '13 at 07:28
  • 1
    I think the `isPrime2` code you have shown has a bug: if you try to test an even number greater than 2 it will return True. Either you need to add another condition or your range has to start from 2 – RafazZ May 16 '15 at 21:43
  • Might i add, that using `math.sqrt` appears to be slightly faster than `** .5` (tested with timeit, Python 3) – FlipTack Dec 30 '16 at 14:55
  • Is there chance that float rounding error would cause a perfect square to result in a prime number, i.e., math.sqrt(n^2) < n – vossman77 Mar 10 '17 at 18:35
  • The loop only needs to be evaluated every 6th number. Could somebody explain why? – YQ.Wang Dec 16 '19 at 06:31
  • @YQ.Wang In case you're still wondering (or if anyone else is confused), refer to elssar's comment above. It says: "All prime numbers, other than 2 & 3, are of the form 6n+/-1". I'm not sure why this is a property of prime numbers, but you can visualise it if you look up "prime numbers" on Google Images – JolonB Apr 29 '20 at 08:08
  • @JolonB All primes are in the form 6n+/-1 due to the following: All integers can be written in the form 6n-3, 6n-2, 6n-1, 6n, 6n+1, 6n+2 or 6n+3, where n is some integer. Any integer in the form 6n+/-3 is divisible by 3. Any integer in the form 6n+/-2 is divisible by 2. Any integer in the form 6n is divisible by 6. Only those written in the form 6n+/-1 have no obvious factors (2 and 3 are exceptions as they are the only ones that are prime but also divide by 2 and 3). Hope this helps! – Garam Lee Sep 05 '21 at 08:48
22

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.

mwfearnley
  • 3,303
  • 2
  • 34
  • 35
cpuguy89
  • 221
  • 1
  • 2
  • The reason the square root is the halfway point is that every pair of divisors will fall either side of the square root, or - if they are both the same (if it's a square number) - will be the square root exactly. – mwfearnley Apr 22 '14 at 01:21
17

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.

Andriy Makukha
  • 7,580
  • 1
  • 38
  • 49
Daniel
  • 326
  • 2
  • 6
  • Also does this reach a point in which the speed starts becoming deficient, comparitively to some of the other functions, The test that I am using this within while using list comprehension starts crying if I go into the realm of 100000, after which it starts breaking down in a speed aspect, not too sure why since it's just a list comprehension on a basic algebraic point, to look at not understand. – L.P. Nov 05 '15 at 02:11
  • I'm sorry about that, but I cant explain it to you. I've found it while searching for a short solution and thought it was a nice one and wanted to share it with you :-). – Daniel Nov 07 '15 at 18:21
  • 2
    You can replace the 2**Number%Number by pow(2, Number, Number), it will be more efficient for big numbers) – Arglanir May 16 '16 at 19:35
  • 2
    This test seems to be close to [Lucas' primality test](https://en.wikipedia.org/wiki/Lucas_primality_test). In order to be complete, we would need to check that `2**((Number-1)/k)` for all k prime factors of `Number-1` are also equal to 1. The wikipedia page gives the full complete algorithm. – Arglanir May 16 '16 at 19:58
  • @AhaanS.Rungta, change the line `return 2 in [Number,2**Number%Number]` by `return 2 in [Number,2**Number%Number] and n%3!=0` and will work for 561. :-) – Sidon Mar 21 '19 at 17:23
  • In fact with the code I suggested in my before comment it does not work for the prime `3`, to fix: `return (2 in [n, 2**n%n] and n%3!=0) or n==3` – Sidon Mar 21 '19 at 17:33
  • 3
    This fails for all Fermat pseudoprimes oeis.org/A001567: 341, 561, 645, 1105, ... It is a pseudo-primality test based on "Fermat's Little(!) Thm.: a^p = a (mod p) if p is prime", but not "only if". – Max Mar 13 '20 at 22:08
15

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
nbro
  • 15,395
  • 32
  • 113
  • 196
ncmathsadist
  • 4,684
  • 3
  • 29
  • 45
  • Yes. If there is a factor k with 1 < k < n, then n/k is also a factor. One of these must be less than the square root of n. – ncmathsadist Mar 08 '13 at 02:22
  • I fixed a small coding error in the consequent of your second if statement by commenting out the erroneous line and inserting a new correct line. Your original program incorrectly reported that 2 is not prime. – user448810 Mar 08 '13 at 02:43
  • 1
    @ncmathsadist Could you explain the block with the variable `k`? I think of it as `while k(3) * k(3) <= n(9), if n(9) % k(3) == 0 (which does equal 0 here), then return false and then increment k to be k(3) = k(3) + 2 which is 5`. What are you doing here? And why `k = k + 2`? Now that `k(5) * k(5) = 25 is no longer <= n(9)` then what? – Edison May 17 '20 at 07:43
  • 1
    @Edison The increment is 2 and not 1 for k because, the divisibility for even numbers is already covered from the second if statement. So, incrementing with 1 is waste of resource. – Rakib Fiha Oct 04 '20 at 13:02
  • @ncmathsadist If k is a factor of n, then one of {k, n/k} is less then ***or equal to*** n. (Consider the case where n is a perfect square, and n = k*k). – AndyB Feb 03 '21 at 08:09
12

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
WW00WW
  • 417
  • 4
  • 15
aikramer2
  • 1,283
  • 12
  • 9
5

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.

dibble
  • 299
  • 3
  • 3
5
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
nbro
  • 15,395
  • 32
  • 113
  • 196
likarson
  • 95
  • 1
  • 2
  • 3
    Take this example just as a **less efficient** alternative implementation that you should **not** use, but instead you should use the [algorithm by @ncmathsadist](http://stackoverflow.com/a/15285590/3924118), which is better in terms of performance. Just to make an example. I have tried to run the same algorithm that @ncmathsadist is using in a loop from `0` to `100000` and it took 0.3 seconds (rounded), while this one took 63 seconds. You are free to use whatever you want, but this quite bad compared to the [algorithm by @ncmathsadist](http://stackoverflow.com/a/15285590/3924118). – nbro Jan 19 '16 at 03:11
  • This algorithm is very similar to [this one](http://stackoverflow.com/a/30404194/3924118), both in terms of performance and implementation. – nbro Jan 19 '16 at 03:14
4

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.

3
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)
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
namco
  • 6,208
  • 20
  • 59
  • 83
  • 1
    This is the most interesting example that I found so far (because it uses recursion), except that it doesn't work. It doesn't handle, for example, the case `num = 1`. If you fix your algorithm, I'll remove my downvote. – nbro Jan 18 '16 at 19:56
  • In order to have your function working properly, you just have to add this after the if statement: `elif num == 1: return False` – CCBet Jan 05 '19 at 12:02
3
def is_prime(x):  
    if x < 2:  
        return False  
    for n in range(2, (x) - 1):  
        if x % n == 0:  
            return False  
    return True
nbro
  • 15,395
  • 32
  • 113
  • 196
  • Take this example just as a **less efficient** alternative implementation that you should **not** use, but instead you should use the [algorithm by @ncmathsadist](http://stackoverflow.com/a/15285590/3924118), which is better in terms of performance. Just to make an example. I have tried to run the same algorithm that @ncmathsadist is using in a loop from `0` to `100000` and it took 0.3 seconds (rounded), while this one took 62 seconds. You are free to use whatever you want, but this quite bad compared to the [algorithm by @ncmathsadist](http://stackoverflow.com/a/15285590/3924118). – nbro Jan 19 '16 at 03:13
  • This algorithm is very similar to [this one](http://stackoverflow.com/a/25276067/3924118), both in terms of performance and implementation. – nbro Jan 19 '16 at 03:15
3

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.

Stephen-Njoroge
  • 145
  • 2
  • 10
2
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.

test30
  • 3,496
  • 34
  • 26
2

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

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • I have no idea if this works, but the performance of your function is quite worse than a simple **not clever** algorithm that uses divisions, i.e. an algorithm that checks all numbers up to `n`. For example, [this](http://stackoverflow.com/a/25276067/3924118) takes roughly 0.8 seconds to check primality for all numbers from 0 to 10000, while yours took 19 seconds on my machine. – nbro Jan 19 '16 at 03:23
  • 1
    @nbro first, pay attention to the line in the answer that says: "If you want to come out as a real smartass". I did not claim that its performance is good, and since it uses regex - it's obviously not! Now, if you want to understand how it works, go to the link at the end of the answer and invest 10-20 minutes in reading it. It's simple yet brilliant! – Nir Alfasi Jan 19 '16 at 05:47
  • Yes, I will try to have a look at that article, because it might be interesting. What I wanted to point out is that suggesting an algorithm that is a lot worse than a simpler one might not be a good idea. Yours is just pretty, not good. Thanks anyway for sharing! – nbro Jan 19 '16 at 13:54
  • 1
    @nbro mathematics is full of such examples (beautiful things that are not useful/optimized at the moment). But sometimes, 200-300 years after something is considered only "beautiful" - we find that it's also useful. Take Fermat last theorem for example :) – Nir Alfasi Jan 19 '16 at 15:30
2

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.

Vipin Rai
  • 149
  • 1
  • 8
2

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)
madeinQuant
  • 1,721
  • 1
  • 18
  • 29
  • This is probably among the fastest as it both replaces quare root with square, and leaves out not only the multiplies of 2 from the loop but the multiplies of 3 as well. – csonti Nov 23 '18 at 07:48
  • This could be improved by creating a list of primes. You need only check `n%primes[index] == 0` – Psionman Aug 10 '20 at 07:52
0

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
O.rka
  • 29,847
  • 68
  • 194
  • 309
0
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
Ayo
  • 1
  • 1
0

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
atline
  • 28,355
  • 16
  • 77
  • 113
0
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
0

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
0

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
    
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 15 '22 at 00:38
  • 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. – THUMMA VIJAY REDDY HP21CSCI020 Jan 15 '22 at 00:41
  • Please [edit] that into your answer instead of leaving it as a comment. – Jeremy Caney Jan 15 '22 at 00:48
0

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
ghost_25423
  • 1
  • 1
  • 1
0

or you can add a count number to optimize like:

`def isPrime(x):
    count = 0
    for i in range(1, x + 1):
        if (x % i == 0):
            count += 1       
    if (count == 2):
        return True
    else:
        return False
    
print(isPrime(x))
`
  • 1
    Hi, welcome to stackoverflow !! Your idea is right - that if the number of divisors is 2 then it is prime. But if you see in your program, you are trying to divide x with all integers till x itself. In the answers given above and even in the question itself, you need to check only until the square root of (x) - not beyond that. So this can be more efficient if you check for divisibility only till sqrt(x). – Sumit S Jun 26 '23 at 17:44
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 27 '23 at 00:47
-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
Mouneer
  • 12,827
  • 2
  • 35
  • 45
-1
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

chinmay rakshit
  • 220
  • 3
  • 11
-1

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.

AkshayJain
  • 65
  • 1
  • 9
-1

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
eslam samy
  • 71
  • 1
  • 3
-1

(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
Joshua
  • 1
-3
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
Ethan
  • 2,754
  • 1
  • 21
  • 34
-4

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
AGSoldier
  • 1
  • 4
  • 2
    Because CS is not about knowing a/the programming language, but rather to know how to use the language in the most optimal way. The code you use will work just fine, but is slow. If you put just a little bit of thought into it, you can write a much better primality test with complexity of `O(sqrt(n))` (like @dawg explained). Your code runs in `O(n)`. This is a problem for primality test, partially because it uses `modulus(%)` operator which by definition is one of the slowest functions (unless it's `%2`) – RafazZ May 17 '15 at 21:04