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

Categories

Resources