Optimize performance - writing out Prime Numbers - python

The issue is Prime Numbers -that the solution is not implemented effectively.
I hear about eratosthenes sieve.
What are the other methods of implementing prime numbers - in a more efficient way?
n = int(input())
suma = 0
m = 0
while m < n:
if n > 100000:
break
x = int(input())
if 1 < x < 10000:
for i in range(x):
if x % (i + 1) == 0:
suma += 1
if suma == 2 and x != 2:
m += 1
print('o')
suma = 0
else:
m += 1
print('x')
suma = 0
The one of solution: https://medium.com/#dhruvpatel1057/generate-prime-numbers-in-python-using-segmented-sieve-of-eratosthenes-245b79da6687

You are using a very naive approach for primality checking.
As a general naive but not so much method, I'd recommend using Wilson's theorem as prime checker. Using math.factorial instead of a python loop should provide you with some reasonable speed increase while keeping the code fairly simple.

I hear about eratosthenes sieve - but not idea, how to implement it.
That's not the sieve of eratosthenes proper but what people usually talk about when they mention it is that when you find a prime you go through all your candidates and remove its factors ("sieving" them out hence the name) and the new first candidate is the next prime in the sequence.
There are more efficient primality tests than sieving everything though, check the "primality test" wikipedia page for examples.

This code will generate the amount of prime numbers the user asked for. It is very efficient, and can work out the first thousand prime numbers in milliseconds.
amount = int(input("Enter the amount of prime numbers you would like to see: "))
primes = []
num = 1
while len(primes) < amount:
num += 1
# If num is bigger than 1, and is 2 or is odd, and when divided by all the number from 3 to num's square root plus 1 (excluding even numbers), there is always a remainder.
if num > 1 and (num == 2 or num % 2 != 0) and all(num % divisor != 0 for divisor in range(3, int(num ** 0.5) + 1, 2)):
primes.append(num)
print(f"The first {amount} prime numbers are:\n{primes}")

this is sample code , make a list of prime, and from this list check the number to process is getting divided or not , if it is not getting divided then it is prime else it is not
# your code goes here
x = int(input())
prime =[]
for i in range(2,x):
if i not in prime:
if prime == []:
prime.append(i)
else:
check = 1
for j in prime:
if i%j==0:
check = 0
break
if check:
prime.append(i)
print(prime)

Related

Python code that creates list of prime numbers

Trying to create a list of prime numbers in a fixed range. This is producing non-sensical list but the code makes sense to me.
for number in range(2,100,2):
k = 1
while k*k < number:
k += 2
if number % k == 0:
break
else:
print(number)
there are several bugs in your code.
first, you don't check its divisibility by even numbers, any even number to be exact (including 2)! if it is meant as an optimization approach, make it more generic by not checking the numbers who are known already not to be prime. its called the sieve of eratosthenes
another, is that you don't check the divisibility if n is a square root of a prime number as you pass the k*k = number case.
this is my implementation for a naive n * sqrt(n):
for number in range(2,100):
prime, divisor = True, 2
while prime and divisor ** 2 <= number:
if number % divisor == 0:
prime = False
divisor += 1
if (prime):
print(number)
Change like this:
for number in range(2, 101):
for k in range(2, number):
if (number % k) == 0:
break
else:
print(number)
for number in range(1,100):
counter=0
for test in range(1,number+1):
if number%test==0:
counter=counter+1
if counter<=2:
print(number)

Calculating the thousandth prime

The problem asks to calculate the 1000th prime number. I am trying to solve this problem but I am stuck.
There are some guidelines on how to solve the problem.
To help you get started, here is a rough outline of the stages you should probably follow in
writing your code:
Initialize some state variables
Generate all (odd) integers > 1 as candidates to be prime
For each candidate integer, test whether it is prime
One easy way to do this is to test whether any other integer > 1 evenly
divides the candidate with 0 remainder. To do this, you can use modular
arithmetic, for example, the expression a%b returns the remainder after
dividing the integer a by the integer b.
You might think about which integers you need to check as divisors –
certainly you don’t need to go beyond the candidate you are checking, buthow much sooner can you stop checking?
If the candidate is prime, print out some information so you know where you are
in the computation, and update the state variables
Stop when you reach some appropriate end condition. In formulating this
condition, don’t forget that your program did not generate the first prime (2).
Use these ideas to guide the creation of your code.
My attempt so far is this
def calculate_thousandth_prime():
j = 0
for i in range(3,int(10e6)):
if i%2 != 0:
counter = 0
for k in range(1, i):
if i%k != 0:
counter += 1
if counter == 0:
print("This candidate is prime")
j += 1
if j == 1001:
print("The number "+str(i)+" is the thousandth prime")
break
return 0
calculate_thousandth_prime()
My code gets stuck on i%k != 0. I must be doing something wrong... any help?
You have two problems:
First, you're searching for k in range(1, i):. Because every number, including primes, is divisible by 1, you won't find any primes. Try searching range(2, i) instead.
Second, you're checking if i%k != 0:. You should be checking that i%k == 0 instead. If i is divisible by any number k, then the number is not prime.
Actually, I found a third issue: You have an off-by-one error. By initializing j=0, your code considers the first prime it finds to be the "zeroth" prime. The code will output the thousand-and-first prime, instead of the thousandth prime.
Changes I made:
Change your range to add a 2 step to skip even numbers more naturally.
Check your inner loop, you need to divide by the values range(2, i//2). Dividing by anything greater than i//2 will be less than 2.
Change your prime check to see if any number in the above range divides. If so, we know the number is false. At that point we can move onto the next number.
We want to return when the prime counter is 1000, you were returning the 1001th prime.
def calculate_thousandth_prime():
prime_counter = 0
for i in range(3,int(10e6),2):
prime = True
for k in range(2, i//2):
if i % k == 0:
prime = False
break
if prime:
print(str(i) + " is prime")
prime_counter += 1
if prime_counter == 1000:
print("The number "+str(i)+" is the thousandth prime")
break
return i
calculate_thousandth_prime()
The sieve of Eratosthenes is generally the fastest way for the early primes. You can adapt it to reach the nth prime.
For example:
def nthPrime(N):
sieve = [1]*(N**2)
p = 2
for _ in range(N):
while not sieve[p]: p += 1
sieve[p::p] = [0]*len(sieve[p::p])
return p
nthPrime(100) # 541
The prime list divisor check method is probably easier to write and understand but it is much slower (although for only 1000 primes, this wouldn't make much of a difference):
def nthPrime(N):
primes = [2]
p = 1
while len(primes)<N:
p += 2
primes += [p]*all(p%d for d in primes)
return p

Prime number finder including 2 multiple times

This program makes a list of all prime numbers less than or equal to a given input.
Then it prints the list.
I can't understand why it includes the number 2. When I first designed the program, I initialized the list with primes = [2] because I thought, since 2 % 2 == 0,
if n % x == 0:
is_prime = False
will set is_prime to False. However, that doesn't seem to be the case.
I'm sure there is something going on with the logic of my range() in the for loops that I just don't understand.
I guess my question is: Why is 2 included in the list of primes every time?
import math
limit = int(input("Enter a positive integer greater than 1: "))
while limit < 2:
limit = int(input("Error. Please enter a positive integer greater than 1: "))
primes = []
#Check all numbers n <= limit for primeness
for n in range (2, limit + 1):
square_root = int(math.sqrt(n))
is_prime = True
for x in range(2, (square_root + 1)):
if n % x == 0:
is_prime = False
if is_prime:
primes.append(n)
#print all the primes
print("The primes less than or equal to", limit, "are:")
for num in primes:
print(num)
Because you don't enter the second for-loop when you test for n=2 and therefore you don't set is_prime = False.
# Simplified test case:
x = 2
for idx in range(2, int(math.sqrt(x))+1):
print(idx)
This doesn't print anything because range is in this case: range(2, 2) and therefore has zero-length.
Note that your approach is not really efficient because:
you test each number by all possible divisors even if you already found out it's not a prime.
you don't exclude multiples of primes in your tests: if 2 is a prime, every multiple of 2 can't be prime, etc.
There are really great functions for finding prime numbers mentioned in Fastest way to list all primes below N - so I won't go into that. But if you're interested in improvements you might want to take a look.

Prime factorization: doesn't work with large numbers?

I'm trying to find the largest prime factor for a number. The code runs correctly on IDLE when used with smaller numbers, but doesn't seem to print anything to the screen at all when I assign a larger number like 600851475143 to n. Why?
def isPrime(n):
isPrime = True
for i in range(2,n-1):
if n % i == 0:
isPrime = False
return isPrime
largest = 0
n = 600851475143
for i in range(2,n-1):
if isPrime(i) and n % i == 0:
largest = i
n = n / i
continue
print("The largest prime factor is", largest)
I'm running Python 3.3, by the way.
==============================================================================
Thanks everyone!
I fixed my original code as follows:
def isPrime(n):
for i in range(2,n-1):
if n % i == 0:
return False
return True
largest = 0
n = 600851475143
for i in range(2,n-1):
if isPrime(i) and n % i == 0:
largest = i
if i == n:
break
n = n / i
print("The largest prime factor is", largest)
Like nakedfanatic said, their code runs faster, and I edited it slightly:
largest = 0
n = 600851475143
i = 2
while True:
if n % i == 0:
largest = i
if n == i:
# finished
break
n = n / i
else:
i += 1
print("The largest prime factor is", largest)
There are several areas of optimization:
all factorization only needs to got up to sqrt(n) (inclusive)
convert isPrime() to a table lookup
Initialize a lookup table using n, then you compute all primes < sqrt(n) only once and loop through them.
As comments pointed out, this takes up large memory space. We can use bit flag to cut the memory requirement to 1/8, and we can cut it by a further half if we skip all the even numbers (then have to test if n is even separately). But that may still be daunting for LARGE n.
(if using current code) return early in isPrime() (by #justhalf)
loop backwards (from sqrt(n) to 2) when looking up the largest factor
return early if the quotient is 1 after dividing by a factor (by #justhalf)
This post (suggested by #prashant) contains more complicated algorithm (making my suggestion very naive ><):
Fastest way to list all primes below N
... (edits are welcome)
It's because you keep trying even if n is already 1.
This code will help you to see the problem:
def isPrime(n):
for i in xrange(2,n-1):
if n % i == 0:
return False
return True
largest = 0
n = 600851475143
for i in xrange(2,n-1):
print 'Checking whether %d divides %d' % (i,n)
if isPrime(i) and n % i == 0:
largest = i
n = n / i
continue
print("The largest prime factor is", largest)
which will produce:
...
Checking whether 6857 divides 6857
Checking whether 6858 divides 1
Checking whether 6859 divides 1
Checking whether 6860 divides 1
Checking whether 6861 divides 1
Checking whether 6862 divides 1
Checking whether 6863 divides 1
Checking whether 6864 divides 1
Checking whether 6865 divides 1
Checking whether 6866 divides 1
Checking whether 6867 divides 1
Checking whether 6868 divides 1
Checking whether 6869 divides 1
Checking whether 6870 divides 1
Checking whether 6871 divides 1
Checking whether 6872 divides 1
Checking whether 6873 divides 1
...
You should break the loop when n becomes 1, so that it won't do unnecessary checking
n = n / i
if n==1:
break
continue
And anyway, your code might be improved by a lot, haha, see others' suggestions.
Most likely, your code isn't terminating with large n, simply because it takes so long to run through the loop.
Your code is running in O(n²) time, which means it will quickly become unreasonably slow as the size of n increases. That is why your algorithm works for small values, but hangs for large values.
This code does the same thing in O(n) time without doing any prime checking at all, and returns a result instantly:
prime_factors = []
n = 600851475143
i = 2
while True:
if n % i == 0:
prime_factors.append(i)
if n == i:
# finished
break
n = n / i
else:
i += 1
print("The largest prime factor is", prime_factors[-1])
More difficult problems may require a different algorithm.
Check this question out: Fastest way to list all primes below N
Your code looks okay, but could take a long time for a large n. Leveraging math can enable you to do this problem orders of magnitude faster.
On that link, I recommend rwh_primes1 for a pure python solution, and primesfrom3to as one that uses numpy. Both of those implementations are fairly short, relatively clear, and do basically the same thing. Those code snippets are written in Python 2, so a translation might look like this:
def rwh_primes1(n):
sieve = [True] * (n//2)
for i in range(3, int(n**0.5)+1,2):
if sieve[i//2]:
sieve[i*i//2::i] = [False] * ((n-i*i-1)//(2*i)+1)
return [2] + [2*i+1 for i in range(1,n//2) if sieve[i]]
isPrime = True
for i in range(2,n-1):
if n % i == 0:
isPrime = False
return isPrime
This loop always exits the first iteration due to the unconditional return. Try:
for i in range(2,n-1):
if n % i == 0:
return False
return True
Also the upper bound n-1 can be reduced to sqrt(n)+1.
Another aspect of your code which may be slowing it down is the second half of your code
largest = 0
n = 600851475143
for i in range(2,n-1):
if isPrime(i) and n % i == 0:
largest = i
n = n / i
continue
Specifically the statement
if isPrime(i) and n % i == 0:
Per the documentation, the second condition is only evaluated if the first one is True. In your case it would make more sense to reverse the conditions so that computationally les expensive division is performed always and the more expensive isPrime() is only called for the actual factors
largest = 0
n = 600851475143
for i in range(2,n-1):
if n % i == 0 and isPrime(i):
largest = i
n = n / i
if n == 1:
break

How to generate the 1000th prime in python?

count = 0
i = 11
while count <= 1000 and i <= 10000:
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
continue
else:
print i,'is prime.'
count += 1
i+=1
I'm trying to generate the 1000th prime number only through the use of loops. I generate the primes correctly but the last prime i get is not the 1000th prime. How can i modify my code to do so. Thank in advance for the help.
EDIT: I understand how to do this problem now. But can someone please explain why the following code does not work ? This is the code I wrote before I posted the second one on here.
count = 1
i = 3
while count != 1000:
if i%2 != 0:
for k in range(2,i):
if i%k == 0:
print(i)
count += 1
break
i += 1
Let's see.
count = 1
i = 3
while count != 1000:
if i%2 != 0:
for k in range(2,i):
if i%k == 0: # 'i' is _not_ a prime!
print(i) # ??
count += 1 # ??
break
i += 1 # should be one space to the left,
# for proper indentation
If i%k==0, then i is not a prime. If we detect that it's not a prime, we should (a) not print it out, (b) not increment the counter of found primes and (c) we indeed should break out from the for loop - no need to test any more numbers.
Also, instead of testing i%2, we can just increment by 2, starting from 3 - they will all be odd then, by construction.
So, we now have
count = 1
i = 3
while count != 1000:
for k in range(2,i):
if i%k == 0:
break
else:
print(i)
count += 1
i += 2
The else after for gets executed if the for loop was not broken out of prematurely.
It works, but it works too hard, so is much slower than necessary. It tests a number by all the numbers below it, but it's enough to test it just up to its square root. Why? Because if a number n == p*q, with p and q between 1 and n, then at least one of p or q will be not greater than the square root of n: if they both were greater, their product would be greater than n.
So the improved code is:
from math import sqrt
count = 1
i = 1
while count < 1000:
i += 2
for k in range(2, 1+int(sqrt(i+1))):
if i%k == 0:
break
else:
# print(i) ,
count += 1
# if count%20==0: print ""
print i
Just try running it with range(2,i) (as in the previous code), and see how slow it gets. For 1000 primes it takes 1.16 secs, and for 2000 – 4.89 secs (3000 – 12.15 ses). But with the sqrt it takes just 0.21 secs to produce 3000 primes, 0.84 secs for 10,000 and 2.44 secs for 20,000 (orders of growth of ~ n2.1...2.2 vs. ~ n1.5).
The algorithm used above is known as trial division. There's one more improvement needed to make it an optimal trial division, i.e. testing by primes only. An example can be seen here, which runs about 3x faster, and at better empirical complexity of ~ n1.3.
Then there's the sieve of Eratosthenes, which is quite faster (for 20,000 primes, 12x faster than "improved code" above, and much faster yet after that: its empirical order of growth is ~ n1.1, for producing n primes, measured up to n = 1,000,000 primes):
from math import log
count = 1 ; i = 1 ; D = {}
n = 100000 # 20k:0.20s
m = int(n*(log(n)+log(log(n)))) # 100k:1.15s 200k:2.36s-7.8M
while count < n: # 400k:5.26s-8.7M
i += 2 # 800k:11.21-7.8M
if i not in D: # 1mln:13.20-7.8M (n^1.1)
count += 1
k = i*i
if k > m: break # break, when all is already marked
while k <= m:
D[k] = 0
k += 2*i
while count < n:
i += 2
if i not in D: count += 1
if i >= m: print "invalid: top value estimate too small",i,m ; error
print i,m
The truly unbounded, incremental, "sliding" sieve of Eratosthenes is about 1.5x faster yet, in this range as tested here.
A couple of problems are obvious. First, since you're starting at 11, you've already skipped over the first 5 primes, so count should start at 5.
More importantly, your prime detection algorithm just isn't going to work. You have to keep track of all the primes smaller than i for this kind of simplistic "sieve of Eratosthanes"-like prime detection. For example, your algorithm will think 11 * 13 = 143 is prime, but obviously it isn't.
PGsimple1 here is a correct implementatioin of what the prime detection you're trying to do here, but the other algorithms there are much faster.
Are you sure you are checking for primes correctly? A typical solution is to have a separate "isPrime" function you know that works.
def isPrime(num):
i = 0
for factor in xrange(2, num):
if num%factor == 0:
return False
return True
(There are ways to make the above function more effective, such as only checking odds, and only numbers below the square root, etc.)
Then, to find the n'th prime, count all the primes until you have found it:
def nthPrime(n):
found = 0
guess = 1
while found < n:
guess = guess + 1
if isPrime(guess):
found = found + 1
return guess
your logic is not so correct.
while :
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
this cannot judge if a number is prime or not .
i think you should check if all numbers below sqrt(i) divide i .
Here's a is_prime function I ran across somewhere, probably on SO.
def is_prime(n):
return all((n%j > 0) for j in xrange(2, n))
primes = []
n = 1
while len(primes) <= 1000:
if is_prime(n):
primes.append(n)
n += 1
Or if you want it all in the loop, just use the return of the is_prime function.
primes = []
n = 1
while len(primes) <= 1000:
if all((n%j > 0) for j in xrange(2, n)):
primes.append(n)
n += 1
This is probably faster: try to devide the num from 2 to sqrt(num)+1 instead of range(2,num).
from math import sqrt
i = 2
count = 1
while True:
i += 1
prime = True
div = 2
limit = sqrt(i) + 1
while div < limit:
if not (i % div):
prime = False
break
else:
div += 1
if prime:
count += 1
if count == 1000:
print "The 1000th prime number is %s" %i
break
Try this:
def isprime(num):
count = num//2 + 1
while count > 1:
if num %count == 0:
return False
count -= 1
else:
return True
num = 0
count = 0
while count < 1000:
num += 1
if isprime(num):
count += 1
if count == 1000:
prime = num
Problems with your code:
No need to check if i <= 10000.
You are doing this
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
Here, you are not checking if the number is divisible by a prime number greater than 7.
Thus your result: most probably divisible by 11
Because of 2. your algorithm says 17 * 13 * 11 is a prime(which it is not)
How about this:
#!/usr/bin/python
from math import sqrt
def is_prime(n):
if n == 2:
return True
if (n < 2) or (n % 2 == 0):
return False
return all(n % i for i in xrange(3, int(sqrt(n)) + 1, 2))
def which_prime(N):
n = 2
p = 1
while True:
x = is_prime(n)
if x:
if p == N:
return n
else:
p += 1
n += 1
print which_prime(1000)
n=2 ## the first prime no.
prime=1 ## we already know 2 is the first prime no.
while prime!=1000: ## to get 1000th prime no.
n+=1 ## increase number by 1
pon=1 ## sets prime_or_not(pon) counter to 1
for i in range(2,n): ## i varies from 2 to n-1
if (n%i)==0: ## if n is divisible by i, n is not prime
pon+=1 ## increases prime_or_not counter if n is not prime
if pon==1: ## checks if n is prime or not at the end of for loop
prime+=1 ## if n is prime, increase prime counter by 1
print n ## prints the thousandth prime no.
Here is yet another submission:
ans = 0;
primeCounter = 0;
while primeCounter < 1000:
ans += 1;
if ans % 2 != 0:
# we have an odd number
# start testing for prime
divisor = 2;
isPrime = True;
while divisor < ans:
if ans % divisor == 0:
isPrime = False;
break;
divisor += 1;
if isPrime:
print str(ans) + ' is the ' + str(primeCounter) + ' prime';
primeCounter += 1;
print 'the 1000th prime is ' + str(ans);
Here's a method using only if & while loops. This will print out only the 1000th prime number. It skips 2. I did this as problem set 1 for MIT's OCW 6.00 course & therefore only includes commands taught up to the second lecture.
prime_counter = 0
number = 3
while(prime_counter < 999):
divisor = 2
divcounter = 0
while(divisor < number):
if(number%divisor == 0):
divcounter = 1
divisor += 1
if(divcounter == 0):
prime_counter+=1
if(prime_counter == 999):
print '1000th prime number: ', number
number+=2
I just wrote this one. It will ask you how many prime number user wants to see, in this case it will be 1000. Feel free to use it :).
# p is the sequence number of prime series
# n is the sequence of natural numbers to be tested if prime or not
# i is the sequence of natural numbers which will be used to devide n for testing
# L is the sequence limit of prime series user wants to see
p=2;n=3
L=int(input('Enter the how many prime numbers you want to see: '))
print ('# 1 prime is 2')
while(p<=L):
i=2
while i<n:
if n%i==0:break
i+=1
else:print('#',p,' prime is',n); p+=1
n+=1 #Line X
#when it breaks it doesn't execute the else and goes to the line 'X'
This will be the optimized code with less number of executions, it can calculate and display 10000 prime numbers within a second.
it will display all the prime numbers, if want only nth prime number, just set while condition and print the prime number after you come out of the loop. if you want to check a number is prime or not just assign number to n, and remove while loop..
it uses the prime number property that
* if a number is not divisible by the numbers which are less than its square root then it is prime number.
* instead of checking till the end(Means 1000 iteration to figure out 1000 is prime or not) we can end the loop within 35 iterations,
* break the loop if it is divided by any number at the beginning(if it is even loop will break on first iteration, if it is divisible by 3 then 2 iteration) so we iterate till the end only for the prime numbers
remember one thing you can still optimize the iterations by using the property *if a number is not divisible with the prime numbers less than that then it is prime number but the code will be too large, we have to keep track of the calculated prime numbers, also it is difficult to find a particular number is a prime or not, so this will be the Best logic or code
import math
number=1
count = 0
while(count<10000):
isprime=1
number+=1
for j in range(2,int(math.sqrt(number))+1):
if(number%j==0):
isprime=0
break
if(isprime==1):
print(number,end=" ")
count+=1

Categories