Finding primes in python - 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
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.
Summation of primes : Using Generator vs w/o Generator
Project Euler 10th problem: Find the sum of all the primes below two million. Well I came up with two solutions : USING GENERATOR FUNCTION def gen_primes(): n = 2 primes = [] while True: for p in primes: if n % p == 0: break else: primes.append(n) yield n n += 1 flag = True sum=0 p=gen_primes() while flag: prime=p.__next__() if prime > 2000000: flag = False else: sum+=prime print(sum) W/O GENERATOR def prime(number): if number ==1: return -1 else: for a in (range(1,int(number**0.5)+1))[::2]: if number%a==0 and a!=1: return False else: return True count=2 for i in (range(1,2000000))[::2]: if prime(i)==True and i!=1: count+=i else: continue print(count) Surprisingly, the latter (w/o g) takes 7.4 seconds whereas the former (using g) takes around 10 minutes !!! Why is it so? Thought the generator would perform better because of fewer steps.
Your generator is doing a lot of unnecessary work. It checks all primes up to n when it only needs to check primes up to the square root of n. Here is a modified version of your generator function with the unnecessary work removed: from time import time t = time() def gen_primes(): primes = [] yield 2 n = 3 while True: is_prime = True upper_limit = n ** .5 for p in primes: if n % p == 0: is_prime = False break elif p > upper_limit: break if is_prime: primes.append(n) yield n n += 2 # only need to check divisibility by odd numbers sum = 0 for prime in gen_primes(): if prime > 2_000_000: break else: sum += prime print("time:", time() - t) print(sum) This takes 2.3 seconds on my computer. The version without the generator takes 4.8 seconds on my computer. If you're interested in a much more efficient algorithm for finding prime numbers, check out the Sieve of Eratosthenes. https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
Here's a rework of your generator code that's almost twice as fast as the non-generator code. Similar to #DanielGiger's solution (+1) but attempts to be simpler and possibly a hair faster. It uses multiple squaring instead of a single square root (may or may not win out) and doesn't need a boolean flag: def gen_primes(): yield 2 primes = [2] number = 3 while True: for prime in primes: if prime * prime > number: yield number primes.append(number) break if number % prime == 0: break number += 2 total = 0 generator = gen_primes() while True: prime = next(generator) if prime > 2_000_000: break total += prime print(total) Here's an equivalent rework of your non-generator code that also attempts to be simpler and just a hair faster. My rule of thumb is to deal with 2 and less as special cases and then write a clean odd divisor check: def is_prime(number): if number < 2: return False if number % 2 == 0: return number == 2 for divisor in range(3, int(number**0.5) + 1, 2): if number % divisor == 0: return False return True total = 2 for i in range(3, 2_000_000, 2): if is_prime(i): total += i print(total) Also, your code generates an entire range of numbers and then throws away the even numbers -- we can use the third argument to range() to generate only the odd numbers in the first place. In the end, the use of a generator has nothing to do with the general performance of your two solutions. You can rewrite your second solution as a generator: def gen_primes(): yield 2 number = 3 while True: for divisor in range(3, int(number**0.5) + 1, 2): if number % divisor == 0: break else: # no break yield number number += 2 The difference between the two solutions is one uses only primes as trial divisors (at the cost of storage) and the other uses odd numbers (pseudoprimes) as trial divisors (with no storage cost). Time-wise, the one that does fewer trial divisions, wins.
Making a prime generator
This is supposed to be a prime generator. I try running this but it doesn't print out the integers. The program will also end right away. I don't know if its running def prime_gen(): start = 1 while start: if start % start == 0: print(start) start += 1
First what is a prime? A number that have no divisors but itself. The easy way is to load that numbers, starting by two and check if that number can't be divided by all the previous ones, if its so then you got a new one; you can make it a generator by using yield instead of return def prime_gen(): primes = [2] yield 2 n = 3 while True: for p in primes: if n % p == 0: n += 1 break else: primes.append(n) yield n Example: pg = prime_gen() next(pg) 2 next(pg) 3 next(pg) 5 next(pg) 7 next(pg) 11
You have 2 main issues here: Your algorithm doesn't calculate primes - it runs infinitely (while start), and prints a number when number % number == 0 (aka number modulo number) which is always true. So this is an infinite loop printing the numbers from 1 up. you never call prime_gen() which is why the program doesn't do anything. You have created a function but did not call it. for a nice way of calculating primes, take a look at Sieve of Eratosthenes (Wikipedia).
You can do something like: def prime_gen(limit): current = 2 # 1 is not exactly prime primes = [] while current <= limit: isPrime = True for p in primes: if current % p == 0: isPrime = False break if isPrime: primes.append(current) print current, ", ", current += 1 return primes
Beginner looking for advice/help on this code (Python) [duplicate]
I was having issues in printing a series of prime numbers from one to hundred. I can't figure our what's wrong with my code. Here's what I wrote; it prints all the odd numbers instead of primes: for num in range(1, 101): for i in range(2, num): if num % i == 0: break else: print(num) break
You need to check all numbers from 2 to n-1 (to sqrt(n) actually, but ok, let it be n). If n is divisible by any of the numbers, it is not prime. If a number is prime, print it. for num in range(2,101): prime = True for i in range(2,num): if (num%i==0): prime = False if prime: print (num) You can write the same much shorter and more pythonic: for num in range(2,101): if all(num%i!=0 for i in range(2,num)): print (num) As I've said already, it would be better to check divisors not from 2 to n-1, but from 2 to sqrt(n): import math for num in range(2,101): if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1)): print (num) For small numbers like 101 it doesn't matter, but for 10**8 the difference will be really big. You can improve it a little more by incrementing the range you check by 2, and thereby only checking odd numbers. Like so: import math print 2 for num in range(3,101,2): if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1)): print (num) Edited: As in the first loop odd numbers are selected, in the second loop no need to check with even numbers, so 'i' value can be start with 3 and skipped by 2. import math print 2 for num in range(3,101,2): if all(num%i!=0 for i in range(3,int(math.sqrt(num))+1, 2)): print (num)
I'm a proponent of not assuming the best solution and testing it. Below are some modifications I did to create simple classes of examples by both #igor-chubin and #user448810. First off let me say it's all great information, thank you guys. But I have to acknowledge #user448810 for his clever solution, which turns out to be the fastest by far (of those I tested). So kudos to you, sir! In all examples I use a values of 1 million (1,000,000) as n. Please feel free to try the code out. Good luck! Method 1 as described by Igor Chubin: def primes_method1(n): out = list() for num in range(1, n+1): prime = True for i in range(2, num): if (num % i == 0): prime = False if prime: out.append(num) return out Benchmark: Over 272+ seconds Method 2 as described by Igor Chubin: def primes_method2(n): out = list() for num in range(1, n+1): if all(num % i != 0 for i in range(2, num)): out.append(num) return out Benchmark: 73.3420000076 seconds Method 3 as described by Igor Chubin: def primes_method3(n): out = list() for num in range(1, n+1): if all(num % i != 0 for i in range(2, int(num**.5 ) + 1)): out.append(num) return out Benchmark: 11.3580000401 seconds Method 4 as described by Igor Chubin: def primes_method4(n): out = list() out.append(2) for num in range(3, n+1, 2): if all(num % i != 0 for i in range(2, int(num**.5 ) + 1)): out.append(num) return out Benchmark: 8.7009999752 seconds Method 5 as described by user448810 (which I thought was quite clever): def primes_method5(n): out = list() sieve = [True] * (n+1) for p in range(2, n+1): if (sieve[p]): out.append(p) for i in range(p, n+1, p): sieve[i] = False return out Benchmark: 1.12000012398 seconds Notes: Solution 5 listed above (as proposed by user448810) turned out to be the fastest and honestly quiet creative and clever. I love it. Thanks guys!! EDIT: Oh, and by the way, I didn't feel there was any need to import the math library for the square root of a value as the equivalent is just (n**.5). Otherwise I didn't edit much other then make the values get stored in and output array to be returned by the class. Also, it would probably be a bit more efficient to store the results to a file than verbose and could save a lot on memory if it was just one at a time but would cost a little bit more time due to disk writes. I think there is always room for improvement though. So hopefully the code makes sense guys. 2021 EDIT: I know it's been a really long time but I was going back through my Stackoverflow after linking it to my Codewars account and saw my recently accumulated points, which which was linked to this post. Something I read in the original poster caught my eye for #user448810, so I decided to do a slight modification mentioned in the original post by filtering out odd values before appending the output array. The results was much better performance for both the optimization as well as latest version of Python 3.8 with a result of 0.723 seconds (prior code) vs 0.504 seconds using 1,000,000 for n. def primes_method5(n): out = list() sieve = [True] * (n+1) for p in range(2, n+1): if (sieve[p] and sieve[p]%2==1): out.append(p) for i in range(p, n+1, p): sieve[i] = False return out Nearly five years later, I might know a bit more but I still just love Python, and it's kind of crazy to think it's been that long. The post honestly feels like it was made a short time ago and at the time I had only been using python about a year I think. And it still seems relevant. Crazy. Good times.
Instead of trial division, a better approach, invented by the Greek mathematician Eratosthenes over two thousand years ago, is to sieve by repeatedly casting out multiples of primes. Begin by making a list of all numbers from 2 to the maximum desired prime n. Then repeatedly take the smallest uncrossed number and cross out all of its multiples; the numbers that remain uncrossed are prime. For example, consider the numbers less than 30. Initially, 2 is identified as prime, then 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 and 30 are crossed out. Next 3 is identified as prime, then 6, 9, 12, 15, 18, 21, 24, 27 and 30 are crossed out. The next prime is 5, so 10, 15, 20, 25 and 30 are crossed out. And so on. The numbers that remain are prime: 2, 3, 5, 7, 11, 13, 17, 19, 23, and 29. def primes(n): sieve = [True] * (n+1) for p in range(2, n+1): if (sieve[p]): print p for i in range(p, n+1, p): sieve[i] = False An optimized version of the sieve handles 2 separately and sieves only odd numbers. Also, since all composites less than the square of the current prime are crossed out by smaller primes, the inner loop can start at p^2 instead of p and the outer loop can stop at the square root of n. I'll leave the optimized version for you to work on.
break ends the loop that it is currently in. So, you are only ever checking if it divisible by 2, giving you all odd numbers. for num in range(2,101): for i in range(2,num): if (num%i==0): break else: print(num) that being said, there are much better ways to find primes in python than this. for num in range(2,101): if is_prime(num): print(num) def is_prime(n): for i in range(2, int(math.sqrt(n)) + 1): if n % i == 0: return False return True
The best way to solve the above problem would be to use the "Miller Rabin Primality Test" algorithm. It uses a probabilistic approach to find if a number is prime or not. And it is by-far the most efficient algorithm I've come across for the same. The python implementation of the same is demonstrated below: def miller_rabin(n, k): # Implementation uses the Miller-Rabin Primality Test # The optimal number of rounds for this test is 40 # See http://stackoverflow.com/questions/6325576/how-many-iterations-of-rabin-miller-should-i-use-for-cryptographic-safe-primes # for justification # If number is even, it's a composite number if n == 2: return True if n % 2 == 0: return False r, s = 0, n - 1 while s % 2 == 0: r += 1 s //= 2 for _ in xrange(k): a = random.randrange(2, n - 1) x = pow(a, s, n) if x == 1 or x == n - 1: continue for _ in xrange(r - 1): x = pow(x, 2, n) if x == n - 1: break else: return False return True
Igor Chubin's answer can be improved. When testing if X is prime, the algorithm doesn't have to check every number up to the square root of X, it only has to check the prime numbers up to the sqrt(X). Thus, it can be more efficient if it refers to the list of prime numbers as it is creating it. The function below outputs a list of all primes under b, which is convenient as a list for several reasons (e.g. when you want to know the number of primes < b). By only checking the primes, it saves time at higher numbers (compare at around 10,000; the difference is stark). from math import sqrt def lp(b) primes = [2] for c in range(3,b): e = round(sqrt(c)) + 1 for d in primes: if d <= e and c%d == 0: break else: primes.extend([c]) return primes
My way of listing primes to an entry number without too much hassle is using the property that you can get any number that is not a prime with the summation of primes. Therefore, if you divide the entry number with all primes below it, and it is not evenly divisible by any of them, you know that you have a prime. Of course there are still faster ways of getting the primes, but this one already performs quite well, especially because you are not dividing the entry number by any number, but quite only the primes all the way to that number. With this code I managed on my computer to list all primes up to 100 000 in less than 4 seconds. import time as t start = t.clock() primes = [2,3,5,7] for num in xrange(3,100000,2): if all(num%x != 0 for x in primes): primes.append(num) print primes print t.clock() - start print sum(primes)
A Python Program function module that returns the 1'st N prime numbers: def get_primes(count): """ Return the 1st count prime integers. """ result = [] x=2 while len(result) in range(count): i=2 flag=0 for i in range(2,x): if x%i == 0: flag+=1 break i=i+1 if flag == 0: result.append(x) x+=1 pass return result
A simpler and more efficient way of solving this is storing all prime numbers found previously and checking if the next number is a multiple of any of the smaller primes. n = 1000 primes = [2] for i in range(3, n, 2): if not any(i % prime == 0 for prime in primes): primes.append(i) print(primes) Note that any is a short circuit function, in other words, it will break the loop as soon as a truthy value is found.
we can make a list of prime numbers using sympy library import sympy lower=int(input("lower value:")) #let it be 30 upper=int(input("upper value:")) #let it be 60 l=list(sympy.primerange(lower,upper+1)) #[31,37,41,43,47,53,59] print(l)
Here's a simple and intuitive version of checking whether it's a prime in a RECURSIVE function! :) (I did it as a homework assignment for an MIT class) In python it runs very fast until 1900. IF you try more than 1900, you'll get an interesting error :) (Would u like to check how many numbers your computer can manage?) def is_prime(n, div=2): if div> n/2.0: return True if n% div == 0: return False else: div+=1 return is_prime(n,div) #The program: until = 1000 for i in range(until): if is_prime(i): print i Of course... if you like recursive functions, this small code can be upgraded with a dictionary to seriously increase its performance, and avoid that funny error. Here's a simple Level 1 upgrade with a MEMORY integration: import datetime def is_prime(n, div=2): global primelist if div> n/2.0: return True if div < primelist[0]: div = primelist[0] for x in primelist: if x ==0 or x==1: continue if n % x == 0: return False if n% div == 0: return False else: div+=1 return is_prime(n,div) now = datetime.datetime.now() print 'time and date:',now until = 100000 primelist=[] for i in range(until): if is_prime(i): primelist.insert(0,i) print "There are", len(primelist),"prime numbers, until", until print primelist[0:100], "..." finish = datetime.datetime.now() print "It took your computer", finish - now , " to calculate it" Here are the resuls, where I printed the last 100 prime numbers found. time and date: 2013-10-15 13:32:11.674448 There are 9594 prime numbers, until 100000 [99991, 99989, 99971, 99961, 99929, 99923, 99907, 99901, 99881, 99877, 99871, 99859, 99839, 99833, 99829, 99823, 99817, 99809, 99793, 99787, 99767, 99761, 99733, 99721, 99719, 99713, 99709, 99707, 99689, 99679, 99667, 99661, 99643, 99623, 99611, 99607, 99581, 99577, 99571, 99563, 99559, 99551, 99529, 99527, 99523, 99497, 99487, 99469, 99439, 99431, 99409, 99401, 99397, 99391, 99377, 99371, 99367, 99349, 99347, 99317, 99289, 99277, 99259, 99257, 99251, 99241, 99233, 99223, 99191, 99181, 99173, 99149, 99139, 99137, 99133, 99131, 99119, 99109, 99103, 99089, 99083, 99079, 99053, 99041, 99023, 99017, 99013, 98999, 98993, 98981, 98963, 98953, 98947, 98939, 98929, 98927, 98911, 98909, 98899, 98897] ... It took your computer 0:00:40.871083 to calculate it So It took 40 seconds for my i7 laptop to calculate it. :)
# computes first n prime numbers def primes(n=1): from math import sqrt count = 1 plist = [2] c = 3 if n <= 0 : return "Error : integer n not >= 0" while (count <= n - 1): # n - 1 since 2 is already in plist pivot = int(sqrt(c)) for i in plist: if i > pivot : # check for primae factors 'till sqrt c count+= 1 plist.append(c) break elif c % i == 0 : break # not prime, no need to iterate anymore else : continue c += 2 # skipping even numbers return plist
You are terminating the loop too early. After you have tested all possibilities in the body of the for loop, and not breaking, then the number is prime. As one is not prime you have to start at 2: for num in xrange(2, 101): for i in range(2,num): if not num % i: break else: print num In a faster solution you only try to divide by primes that are smaller or equal to the root of the number you are testing. This can be achieved by remembering all primes you have already found. Additionally, you only have to test odd numbers (except 2). You can put the resulting algorithm into a generator so you can use it for storing primes in a container or simply printing them out: def primes(limit): if limit > 1: primes_found = [(2, 4)] yield 2 for n in xrange(3, limit + 1, 2): for p, ps in primes_found: if ps > n: primes_found.append((n, n * n)) yield n break else: if not n % p: break for i in primes(101): print i As you can see there is no need to calculate the square root, it is faster to store the square for each prime number and compare each divisor with this number.
How about this? Reading all the suggestions I used this: prime=[2]+[num for num in xrange(3,m+1,2) if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1))] Prime numbers up to 1000000 root#nfs:/pywork# time python prime.py 78498 real 0m6.600s user 0m6.532s sys 0m0.036s
Adding to the accepted answer, further optimization can be achieved by using a list to store primes and printing them after generation. import math Primes_Upto = 101 Primes = [2] for num in range(3,Primes_Upto,2): if all(num%i!=0 for i in Primes): Primes.append(num) for i in Primes: print i
Here is the simplest logic for beginners to get prime numbers: p=[] for n in range(2,50): for k in range(2,50): if n%k ==0 and n !=k: break else: for t in p: if n%t ==0: break else: p.append(n) print p
n = int(input()) is_prime = lambda n: all( n%i != 0 for i in range(2, int(n**.5)+1) ) def Prime_series(n): for i in range(2,n): if is_prime(i) == True: print(i,end = " ") else: pass Prime_series(n) Here is a simplified answer using lambda function.
def function(number): for j in range(2, number+1): if all(j % i != 0 for i in range(2, j)): print(j) function(13)
for i in range(1, 100): for j in range(2, i): if i % j == 0: break else: print(i)
Print n prime numbers using python: num = input('get the value:') for i in range(2,num+1): count = 0 for j in range(2,i): if i%j != 0: count += 1 if count == i-2: print i,
def prime_number(a): yes=[] for i in range (2,100): if (i==2 or i==3 or i==5 or i==7) or (i%2!=0 and i%3!=0 and i%5!=0 and i%7!=0 and i%(i**(float(0.5)))!=0): yes=yes+[i] print (yes)
min=int(input("min:")) max=int(input("max:")) for num in range(min,max): for x in range(2,num): if(num%x==0 and num!=1): break else: print(num,"is prime") break
This is a sample program I wrote to check if a number is prime or not. def is_prime(x): y=0 if x<=1: return False elif x == 2: return True elif x%2==0: return False else: root = int(x**.5)+2 for i in xrange (2,root): if x%i==0: return False y=1 if y==0: return True
n = int(raw_input('Enter the integer range to find prime no :')) p = 2 while p<n: i = p cnt = 0 while i>1: if p%i == 0: cnt+=1 i-=1 if cnt == 1: print "%s is Prime Number"%p else: print "%s is Not Prime Number"%p p+=1
Using filter function. l=range(1,101) for i in range(2,10): # for i in range(x,y), here y should be around or <= sqrt(101) l = filter(lambda x: x==i or x%i, l) print l
for num in range(1,101): prime = True for i in range(2,num/2): if (num%i==0): prime = False if prime: print num
f=0 sum=0 for i in range(1,101): for j in range(1,i+1): if(i%j==0): f=f+1 if(f==2): sum=sum+i print i f=0 print sum
The fastest & best implementation of omitting primes: def PrimeRanges2(a, b): arr = range(a, b+1) up = int(math.sqrt(b)) + 1 for d in range(2, up): arr = omit_multi(arr, d)
Here is a different approach that trades space for faster search time. This may be fastest so. import math def primes(n): if n < 2: return [] numbers = [0]*(n+1) primes = [2] # Mark all odd numbers as maybe prime, leave evens marked composite. for i in xrange(3, n+1, 2): numbers[i] = 1 sqn = int(math.sqrt(n)) # Starting with 3, look at each odd number. for i in xrange(3, len(numbers), 2): # Skip if composite. if numbers[i] == 0: continue # Number is prime. Would have been marked as composite if there were # any smaller prime factors already examined. primes.append(i) if i > sqn: # All remaining odd numbers not marked composite must be prime. primes.extend([i for i in xrange(i+2, len(numbers), 2) if numbers[i]]) break # Mark all multiples of the prime as composite. Check odd multiples. for r in xrange(i*i, len(numbers), i*2): numbers[r] = 0 return primes n = 1000000 p = primes(n) print "Found", len(p), "primes <=", n
Adding my own version, just to show some itertools tricks v2.7: import itertools def Primes(): primes = [] a = 2 while True: if all(itertools.imap(lambda p : a % p, primes)): yield a primes.append(a) a += 1 # Print the first 100 primes for _, p in itertools.izip(xrange(100), Primes()): print p
Finding the largest prime number "within" a number
For this question, I need to find the largest prime number within a larger number. For the purpose of the example, let's say the larger number is "123456789", then some of the numbers I would have to check are 12, 456, 234567, etc. I wrote some Python code to figure this out, but it is running very slow for the number I am trying to check. The actual number I am working with is about 10000 digits, so there are a lot of numbers I need to look at. Here is my code: num = "123456789" def isPrime(n): # 0 and 1 are not primes if n < 2: return False # 2 is the only even prime number if n == 2: return True # all other even numbers are not primes if not n & 1: return False # range starts with 3 and only needs to go up the squareroot of n # for all odd numbers for x in range(3, long(n**0.5)+1, 2): if n % x == 0: return False return True def largestPrime(): largest = 2 for i in range(0,len(num)): for j in range(i+1,len(num)): if isPrime(long(num[i:j])): if long(num[i:j]) > largest: largest =long(num[i:j]) print largest def main(): largestPrime() main() I'm pretty sure this code gives the correct answer, but as I said, it's really slow. Can anyone help me figure out how to speed this up? Thanks for any help!
I'd probably use the strategy of starting with the total number of digits and seeing if that's prime. Then keep decreasing the digits by one while shifting over to the left to see if that's prime. Let me explain with an example: 123456789 First check the 9-digit number: 123456789 Then check the 8-digit numbers: 23456789, 12345678 Then Check the 7-digit numbers: 3456789, 2345678, 1234567 etc.
One problem I see is that for some large numbers you are going to be testing the same number many times. For example for '123456712345671234567', your code will test '1234567' 3 times. I suggest you make a set that contains no duplicates, then run your prime test on each number. I also think that sorting the numbers is a good idea because we can stop after the first prime is found. Next if you are dealing with large numbers (e.g. 10000 digits), I suggest using a statistical primality test. Below I made a Miller-Rabin primality test using pseudocode from wikipedia. I have pretty much rewritten your code :P import random num = '3456647867843652345683947582397589235623896514759283590867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876784235876324650' def probablyPrime(num, k): """Using Miller-Rabin primality test""" if num == 2 or num == 3: return True if num < 2: return False if not num & 1: return False # find s and d such that n−1 = (2**s)*d with d odd d = (num-1) >> 1 s = 1 while not (d & 1): d = d >> 1 s += 1 # run k times for _ in range(k): a = random.randint(2, num-2) x = pow(a, d, num) # more efficient than x = a**d % num if not (x == 1 or x == num-1): for _ in range(s-1): x = (x**2) % num if x == 1: return False if x == num-1: break if not x == num-1: return False return True def largestPrime(num): num_list = set([]) for i in range(0,len(num)+1): for j in range(i+1,len(num)+1): inum = int(num[i:j]) # Don't append numbers that have already appeared if inum not in num_list: num_list.add(inum) # Convert to list and sort num_list = list(num_list) num_list.sort(reverse=True) for num in num_list: print('Checking ' + str(num)) if probablyPrime(num,100): print('\n' + str(num) + ' is probably the largest prime!') return largestPrime(num) Another way to improve speed might be python's multiprocessing package.
Code: def isprime(n): if n == 2: return str(n)+" is the biggest prime" if n % 2 == 0: return isprime(n-1) #not prime, check again for next biggest number max = n**0.5+1 i = 3 while i <= max: if n % i == 0: return isprime(n-1) #not prime, check again for next biggest number i+=2 return str(n)+" is the biggest prime" print "Testing 7:",isprime(7) print "Testing 23:",isprime(23) print "Testing 2245:",isprime(2245) print "Testing 222457:",isprime(222457) print "Testing 727245628:",isprime(727245628) Output: >>> Testing 7: 7 is the biggest prime Testing 23: 23 is the biggest prime Testing 2245: 2243 is the biggest prime Testing 222457: 222437 is the biggest prime Testing 727245628: 727245613 is the biggest prime