Prime numbers using sieve of erathosthenes - python
So I am new to programming in python(and in general) and was doing some coding challenges. I came across this 'prime numbers using the sieve method' challenge. I have successfully managed to attempt it however I feel like my logic needs improvement.
So what I did was use 3 while loops in python, the code works as intended, gives me a set of prime numbers however I cannot find a way to condense it.
import sys
n = int(sys.argv[1])
ls = []
i = 2
while i <= n:
ls.append(i)
i += 1
i = 0
while i < len(ls):
if i == 0:
pass
else:
ls[i] = ''
i += 2
i = 1
while i < len(ls):
if i == 1:
pass
else:
ls[i] = ''
i += 3
i = 0
while i < len(ls):
if i == 0:
pass
else:
ls[i] = ''
i += 5
i = 0
primes = []
while i < len(ls):
if ls[i] != '':
primes.append(ls[i])
i += 1
for prime in primes:
print(prime,end=', ')
As the ceo of nvidia once said, 'it just works' but clearly not in the best way :D
Your code thinks 49 is prime, which is not awesome. Making a while loop for each prime just doesn't work.
Here's a simple version that does:
import math
def primesLessThan(N):
seive = [True] * N
seive[0] = seive[1] = False
for i in range(2,int(math.sqrt(N))+1):
if (seive[i]): # i is prime
for j in range(2*i,N,i): # all multiples of i >= 2i
seive[j] = False # j is composite since i is a factor
return [p for p in range(2,N) if seive[p]]
print(primesLessThan(500))
Related
How to print x amount of answer instead of printing x amount of value?
I found this code on stackoverflow and everything works but I want to change the way it is printed. In this code, it prints everything where the value(n) is prime and up to 100. What I want to do is print the first hundred prime numbers. How do I do this? I have tried some kind of "(primes * 100)" because I thought multiplying it might work but it didn't. Thank you in advance. def primes(n): primeslist = [2] for i in range (2,n): p = 1 for j in primeslist: if (i%j) == 0: p = 0 break if p == 1: primeslist.append(i) return primeslist primeslist = primes(100) print(primeslist)
You can print a slice of your list: print(primeslist[:100]) If you want them in seperate lines: print("\n".join([str(i) for i in primeslist[:100]])) If you want to PRODUCE first 100 primes instead of primes up to value of 100 you must change: for i in range (2,n): to while len(primeslist)<100:
If you want to print first n number of primes, this is one way of doing it. i = 1 while True: i += 1 p = 1 for j in primeslist: if (i%j) == 0: p = 0 break if p == 1: primeslist.append(i) if len(primeslist) == n: return primeslist or this is another way of doing. i = 1 while len(primeslist) == n: i += 1 p = 1 for j in primeslist: if (i%j) == 0: p = 0 break if p == 1: primeslist.append(i) return primeslist
Python algorithms nth prime number
Question: Given the prime number n, output the number of prime numbers My code: def kthPrime(self, n): if n>10 and n%10 not in [1,3,7,9]: return 0 if n == 2: return 1 queue = [] num = 2 while num <= n: if n%num == 0 and num != n: return 0 if num>10 and num%10 not in [1,3,7,9]: num += 1 continue for i in range(2,num/2+1): if num%i == 0: num += 1 break else: queue.append(num) num += 1 seq = queue.index(n) + 1 return seq Error: Your code ran too much time than we expected. Check your time complexity. Time limit exceeded usually caused by infinite loop if your time complexity is the best. My Question: how to improve it
as user #Prune said , please read the guide first. I'm not going to tell you how to improve your function , but I'm just gonna give you a faster way to see whether a number is prime or not and hopefully you will understand how to use the function that I'm gonna give you to improve your own function. The source code : class numChecker: def is_prime(self,n): if n == 2: return True if n % 2 == 0 or n < 2: return False self.square_root = int(n ** (1/2)) for divisor in range(3, self.square_root + 1, +2): if n % divisor == 0: return False return True
Python code for finding the 1001st prime number
I recently started programming Python and was stuck at this particular Project Euler problem for finding the 1001st prime number. My code: L = [2] def is_prime(x,L): for el in L: if x%el != 0: flag = 1 else: flag = 0 break if flag == 1: return True elif flag == 0: return False a = 3 for k in range(1,1002): if is_prime(a,L) is True: L.append(a) a += 1 k += 1 else: a += 1 print(L) print(len(L)) This prints the list of prime numbers upto 997 which is the 168th prime number. Can you tell me what am I doing wrong?
Your increment of k is pointless, because you're iterating a fixed range of numbers (k is replaced when the loop loops, the range can't be changed dynamically). You want a while loop with a manually managed k: a = 3 k = 1 while k < 1002: if is_prime(a,L): L.append(a) a += 1 k += 1 else: a += 1 Note: There may be some off-by-one logic errors here, but it expresses what I assume was your intent in the original code, fixing only the issue with managing k.
k += 1 That's where the problem is. Try this code: for k in range(1, 1002): print(k) and then: for k in range(1, 1002): k += 1 print(k)
Your Mistake is that you are finding numbers that are prime UP to 1001 and Also variables of a loop cannot increase By the user to fix that use a while loop
A Program To Find Up Prime's To Any Number would be: import sys def prime_num_finder(): i = 2 while True: try: p = int(input("Please enter up to what number the prime numbers should be: ")) break except ValueError: sys.stderr.write('ERROR\n') sys.stderr.write(' Try again...\n') while i != (p + 1): x = i if x % 2 and x % 3 and x % 5 and x % 7 > 0.1: # Checks if the remainder is greater than 0.1 to see if it has an remainder r1 = True else: if i == 2 or i == 3 or i == 5 or i == 7: r1 = True else: r1 = False if r1 == True: print(i, " is a prime number!") else: pass i = i + 1 prime_num_finder() quit() That is a simple program to check if it is divisible by 2 ,3, 5, or 7
Wrong Answer to SPOJ PRIME1 in Python
I've tried to compare my result to Wolfram Alpha's result by counting primes found. It seems works well, without error. But when I submit this solution to SPOJ, it shows the error message "wrong answer". I also tried to change the final print's end= to '' (blank string), but still got "wrong answer". Not sure if is there something wrong with my sieve algorithm, or output error. **edit: link of problem http://www.spoj.pl/problems/PRIME1/ Here is my PRIME1 source code, hope someone can point out my fault. Thanks a lot. And hope someone can teach me how to write a test to programs like this, I'm still learning, don't know how to do automated tests to programs, but want to learn. def getPrimeInRange(minNum, maxNum): #just a variation with skipping step of the Sieve of E's processingRange = list(range(minNum, maxNum+1)) #prefix, due to 1 is not a prime if minNum == 1: processingRange[0] = 0 sqrtOfMaxNum = int(maxNum ** 0.5) + 1 primesUnderSqrt = list(range(sqrtOfMaxNum)) #prefix, due to 1 is not a prime primesUnderSqrt[1] = 0 #my strategy is flip all numbers that is not a prime to zero, which equals to False. #for Sieve of E's, all the primes under sqrt of max num are the only needed numbers to sieve primes out. #so here is a smaller Sieve of E's for numbers under sqrt for n in primesUnderSqrt: if n: #which equals to "if n != 0" nowIndex = n + n while True: try: primesUnderSqrt[nowIndex] = 0 nowIndex += n except IndexError: break #full aspect sieve for n in primesUnderSqrt: if n: #for easier flip processing, I need the offset number for the flipping. nMultipleMostCloseToMin = n * (minNum // n) if nMultipleMostCloseToMin == minNum: nowIndex = 0 elif sqrtOfMaxNum <= minNum: nowIndex = nMultipleMostCloseToMin + n - minNum elif sqrtOfMaxNum > minNum: nowIndex = nMultipleMostCloseToMin + n - minNum + n #happy flippin' while True: try: processingRange[nowIndex] = 0 nowIndex += n except IndexError: break return processingRange def main(): todoTimes = int(input()) todoNums = list(range(todoTimes)) stringOutput = '' for i in range(todoTimes): todoNums[i] = input().split() todoNums[i][0] = int(todoNums[i][0]) todoNums[i][1] = int(todoNums[i][1]) for [minNum, maxNum] in todoNums: #countedNum = 0 #for algo debugging for n in getPrimeInRange(minNum, maxNum): if n: stringOutput += str(n) #countedNum += 1 #for algo debugging stringOutput += '\n' stringOutput += '\n' #stringOutput += str(countedNum) #for algo debugging stringOutput = stringOutput.rstrip('\n') print(stringOutput) ifMainSucceed = main()
This part of your logic if nMultipleMostCloseToMin == minNum: nowIndex = 0 elif sqrtOfMaxNum <= minNum: nowIndex = nMultipleMostCloseToMin + n - minNum elif sqrtOfMaxNum > minNum: nowIndex = nMultipleMostCloseToMin + n - minNum + n is wrong. Your elif-conditions don't make much sense here. If n is not a divisor of minNum, the smallest multiple of n not less than minNum is nMultipleMostCloseToMin + n, regardless of whether sqrtOfMaxNum is larger than minNum or not. The condition you intended here was n <= minNum, to avoid crossing off the prime itself.
How can I get this Python code to run more quickly? [Project Euler Problem #7]
I'm trying to complete this Project Euler challenge: 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? My code seem to be right because it works with small numbers, e.g 6th prime is 13. How can i improve it so that the code will run much more quickly for larger numbers such as 10 001. Code is below: #Checks if a number is a prime def is_prime(n): count = 0 for i in range(2, n): if n%i == 0: return False break else: count += 1 if count == n-2: return True #Finds the value for the given nth term def term(n): x = 0 count = 0 while count != n: x += 1 if is_prime(x) == True: count += 1 print x term(10001) UPDATE: Thanks for your responses. I should have been more clear, I am not looking to speed up the interpreter or finding a faster interpreter, because i know my code isn't great, so i was looking for ways of make my code more efficient.
A few questions to ponder: Do you really need to check the division until n-1? How earlier can you stop? Apart from 2, do you really need to check the division by all the multiples of two ? What about the multiples of 3? 5? Is there a way to extend this idea to all the multiples of previously tested primes?
The purpose of Project Euler is not really to think learn programming, but to think about algorithms. On problem #10, your algorithm will need to be even faster than on #7, etc. etc. So you need to come up with a better way to find prime numbers, not a faster way to run Python code. People solve these problems under the time limit with far slower computers that you're using now by thinking about the math. On that note, maybe ask about your prime number algorithm on https://math.stackexchange.com/ if you really need help thinking about the problem.
A faster interpreter won't cut it. Even an implementation written in C or assembly language won't be fast enough (to be in the "about one second" timeframe of project Euler). To put it bluntly, your algorithm is pathetic. Some research and thinking will help you write an algorithm that runs faster in a dog-slow interpreter than your current algorithm implemented in native code (I won't name any specifics, partly because that's your job and partly because I can't tell offhand how much optimization will be needed).
Many of the Euler problems (including this one) are designed to have a solution that computes in acceptable time on pretty much any given hardware and compiler (well, not INTERCAL on a PDP-11 maybe). You algorithm works, but it has quadratic complexity. Using a faster interpreter will give you a linear performance boost, but the quadratic complexity will dwarf it long before you calculate 10,000 primes. There are algorithms with much lower complexity; find them (or google them, no shame in that and you'll still learn a lot) and implement them.
Without discussing your algorithm, the PyPy interpreter can be ridiculously faster than the normal CPython one for tight numerical computation like this. You might want to try it out.
to check the prime number you dont have to run till n-1 or n/2.... To run it more faster,you can check only until square root of n And this is the fastest algorithm I know def isprime(number): if number<=1: return False if number==2: return True if number%2==0: return False for i in range(3,int(sqrt(number))+1): if number%i==0: return False return True
As most people have said, it's all about coming up with the correct algorithm. Have you considered looking at a Sieve of Eratosthenes
import time t=time.time() def n_th_prime(n): b=[] b.append(2) while len(b)<n : for num in range(3,n*11,2): if all(num%i!=0 for i in range(2,int((num)**0.5)+1)): b.append(num) print list(sorted(b))[n-1] n_th_prime(10001) print time.time()-t prints 104743 0.569000005722 second
A pythonic Answer import time t=time.time() def prime_bellow(n): b=[] num=2 j=0 b.append(2) while len(b)-1<n: if all(num%i!=0 for i in range(2,int((num)**0.5)+1)): b.append(num) num += 1 print b[n] prime_bellow(10001) print time.time()-t Prints 104743 0.702000141144 second
import math count = 0 <br/> def is_prime(n): if n % 2 == 0 and n > 2: return False for i in range(3, int(math.sqrt(n)) + 1, 2): if n % i == 0: return False return True for i in range(2,2000000): if is_prime(i): count += 1 if count == 10001: print i break
I approached it a different way. We know that all multiples of 2 are not going to be prime (except 2) we also know that all non-prime numbers can be broken down to prime constituents. i.e. 12 = 3 x 4 = 3 x 2 x 2 30 = 5 x 6 = 5 x 3 x 2 Therefore I iterated through a list of odd numbers, accumulating a list of primes, and only attempting to find the modulus of the odd numbers with primes in this list. #First I create a helper method to determine if it's a prime that #iterates through the list of primes I already have def is_prime(number, list): for prime in list: if number % prime == 0: return False return True EDIT: Originally I wrote this recursively, but I think the iterative case is much simpler def find_10001st_iteratively(): number_of_primes = 0 current_number = 3 list_of_primes = [2] while number_of_primes <= 10001: if is_prime(current_number, list_of_primes): list_of_primes.append(current_number) number_of_primes += 1 current_number += 2 return current_number
A different quick Python solution: import math prime_number = 4 # Because 2 and 3 are already prime numbers k = 3 # It is the 3rd try after 2 and 3 prime numbers milestone = 10001 while k <= milestone: divisible = 0 for i in range(2, int(math.sqrt(prime_number)) + 1): remainder = prime_number % i if remainder == 0: #Check if the number is evenly divisible (not prime) by i divisible += 1 if divisible == 0: k += 1 prime_number += 1 print(prime_number-1)
import time t = time.time() def is_prime(n): #check primes prime = True for i in range(2, int(n**0.5)+1): if n % i == 0: prime = False break return prime def number_of_primes(n): prime_list = [] counter = 0 num = 2 prime_list.append(2) while counter != n: if is_prime(num): prime_list.append(num) counter += 1 num += 1 return prime_list[n] print(number_of_primes(10001)) print(time.time()-t) 104743 0.6159017086029053
based on the haskell code in the paper: The Genuine Sieve of Eratosthenes by Melissa E. O'Neill from itertools import cycle, chain, tee, islice wheel2357 = [2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10] def spin(wheel, n): for x in wheel: yield n n = n + x import heapq def insertprime(p,xs,t): heapq.heappush(t,(p*p,(p*v for v in xs))) def adjust(t,x): while True: n, ns = t[0] if n <= x: n, ns = heapq.heappop(t) heapq.heappush(t, (ns.next(), ns)) else: break def sieve(it): t = [] x = it.next() yield x xs0, xs1 = tee(it) insertprime(x,xs1,t) it = xs0 while True: x = it.next() if t[0][0] <= x: adjust(t,x) continue yield x xs0, xs1 = tee(it) insertprime(x,xs1,t) it = xs0 primes = chain([2,3,5,7], sieve(spin(cycle(wheel2357), 11))) from time import time s = time() print list(islice(primes, 10000, 10001)) e = time() print "%.8f seconds" % (e-s) prints: [104743] 0.18839407 seconds from itertools import islice from heapq import heappush, heappop wheel2357 = [2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2, 4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10] class spin(object): __slots__ = ('wheel','o','n','m') def __init__(self, wheel, n, o=0, m=1): self.wheel = wheel self.o = o self.n = n self.m = m def __iter__(self): return self def next(self): v = self.m*self.n self.n += self.wheel[self.o] self.o = (self.o + 1) % len(self.wheel) return v def copy(self): return spin(self.wheel, self.n, self.o, self.m) def times(self, x): return spin(self.wheel, self.n, self.o, self.m*x) def adjust(t,x): while t[0][0] <= x: n, ns = heappop(t) heappush(t, (ns.next(), ns)) def sieve_primes(): for p in [2,3,5,7]: yield p it = spin(wheel2357, 11) t = [] p = it.next() yield p heappush(t, (p*p, it.times(p))) while True: p = it.next() if t[0][0] <= p: adjust(t,p) continue yield p heappush(t, (p*p, it.times(p))) from time import time s = time() print list(islice(sieve_primes(), 10000, 10001))[-1] e = time() print "%.8f seconds" % (e-s) prints: 104743 0.22022200 seconds import time from math import sqrt wheel2357 = [2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10] list_prime = [2,3,5,7] def isprime(num): limit = sqrt(num) for prime in list_prime: if num % prime == 0: return 0 if prime > limit: break return 1 def generate_primes(no_of_primes): o = 0 n = 11 w = wheel2357 l = len(w) while len(list_prime) < no_of_primes: i = n n = n + w[o] o = (o + 1) % l if isprime(i): list_prime.append(i) t0 = time.time() generate_primes(10001) print list_prime[-1] # 104743 t1 = time.time() print t1-t0 # 0.18 seconds prints: 104743 0.307313919067