Determining whether a number is prime or not - python

I know it's been discussed many times; I've read it, but somehow I can't get it.
I want to write a program that determines if the entered number is prime or not.
One of the implementations I found somewhere on the Internet:
from math import *
def main():
n = abs(input("Enter a number: "))
i = 2
msg = 'is a prime number.'
while i <= sqrt(n):
if n % i == 0:
msg = 'is not a prime number.'
i = i + 1
print n, msg
main()
A couple of questions here:
In the above, what is i, and why does it have a starting value of 2?
What does i = i + 1 do in this program?
How does the interpreter know when to print 'is a prime number.' even though it is out of the body loop?

A prime number is a number that's only divisible by 1 and itself. The method it's using is to try dividing your candidate number n by every other number from 2 up to itself; however if any number i is a divisor of your number n then so is n / i and at least one of them is less than or equal to sqrt(n) therefore we need only test up to sqrt(n) inclusive. In practice we need only test the divisors that are actually prime themselves but since we don't have a list of primes to hand we'll test every one.
what in the above i is? and why it got a 2 starting value?
i is the potential factor of n we're testing. It starts with 2 because we don't care if 1 divides n (and trivially it will) because the prime definition allows / expects that.
what is the i = i + 1 statement, in this concrete example for? Can't see its use in the program.
It's incrementing the i value at the end of the loop defined by the while i <= sqrt(n); it means we advance i to test the next candidate divisor of n.
and finally, how python knows when to print 'is a prime number.' although it is out of the body loop?
We initialise msg to "is a prime number" and if we find any divisor then we change it to "is not a prime number" inside the loop. If the loop doesn't find a divisor, or if the loop never runs, we'll use the initial value we set which is "is a prime number". Incidentally you could break out of the loop when you find a divisor; there's no point carrying on the test after that.
As another aside you probably want to compute sqrt(n) outside the while and store than in a variable to use in the while - you may be recalculating the square root for every iteration, which is relatively expensive.

I've added comments on the sides to explain what each line does:
from math import * # imports everything from the math module
def main():
n = abs(input("Enter a number: ")) # gets input from the user
i = 2 # starts off at 2 because all input is divisble by 1
msg = 'is a prime number.' # the message is initially set
while i <= sqrt(n):
if n % i == 0: # if 'i' divides evenly into n
msg = 'is not a prime number.' # only set if it isn't a prime
i = i + 1 # increases 'i' by 1 so it can check every value up to the square-root of 'n' (to see if it divides evenly)
print n, msg
main()
The program has to go through every value of i (up to the square-root of n) so that every possible factor is checked.
This is sort of a rough-prime checker, and inefficient for large numbers that aren't prime:
If the input was a number like 1234567890, it will iterate through every number up to the square root of that number, which is 35147 (rounded up).
Using return statements break the loop, so the first number you check, 2, it is declared not prime since it is evenly divisible by 2.
By using return, it will stop the function, and save you 35,146 calculations. That isn't a massive number (for computers, at least) but it's still more memory-efficient and takes less time.
def isPrime(n):
'''Checks if 'n' is prime.'''
from math import sqrt
if n == 0 or n == 1:
return False
else:
for check in range(2, int(sqrt(n))+1):
if n % check == 0: return False
return True

Related

Is there a way of checking if a value is evenly divisible by any value in a given data set?

I am currently attempting to write a simple bit of python 3 code that allows the user to tell the program which prime number it wants to find and then return the number to the user. I have hit a roadblock because I need to check if the "newprime" value is in fact a prime, which requires me to divide the value by all the previous prime numbers ("primes") and then checking if the answer is a whole number or not. Here is the current program
import numpy
primes = [2]
print("the how many-th prime would you like to calculate?")
numberOfPrime = int( input() )
x = 0
while x <= numberOfPrime:
notprime = 0 #placeholder, should be all numbers which when divided by any of the set "primes" gives a whole number
while newprime == notprime:
newprime = primes[x] + 1
primes.append(newprime)
print(primes)
x += 1
print(primes[numberOfPrime], " is the ", numberOfPrime, "-th prime number", sep="")
As you can see, I added a comment where I would have to insert the missing part.
How do I best approach this?

Check if a number is a prime by counting zero remainders

I am trying to write a program which checks if a number is a prime number or not.
The way I already know: Check if any of the numbers, excluding the number itself and 1, gives a reminder of zero.
The way I want to try: Check if more than two numbers, including 1 and the number itself, are giving a reminder of zero:
n=10
for a in range(1,n+1):
x=n%a
if (x == 0):
print x
I am getting the number of instances when the reminder is zero with code mentioned. I want to define the logic in such a way that if number of zeros is greater than 2 in the output, then the number is not prime, else the number is prime. (Expecting that the input number is greater than 1.)
I think folks are confused and avoiding this as it's not an efficient way to check for primes. Usually, we desire to disqualify a number as quickly and easily as possible, avoiding doing any extra divisions.
However, if it's what you want, here's an implementation:
def is_prime(n):
'''
I want to define the logic in such that if the number
of zeros is greater than 2 in the output, then the number
is not prime, else the number is prime
'''
return sum(n % divisor == 0 for divisor in range(1, n + 1)) <= 2
# Expecting that the input number is greater than 1
for n in range(2, 100):
if is_prime(n):
print(n)

Python Script Not Finishing

I am trying to run my code to try to solve euler problem number 10. I am very new to python and my code has been going very slowly and in this case never ending. Any help would be appreciated. Thank you.
primes = [2]
number = 2
y=1
while y <=1:
for i in primes:
if number % i == 0:
break
else:
if i == primes[-1]:
primes.append(number)
if (primes[-1]) >= 2000000:
del primes[-1]
y += 2
number+=1
print(sum(primes))
SPOILER ALERT: the following contains the answer to question 10 in Project Euler.
Your problem is that your code take too long to run, that is because it is checking too many thing and will take too long to work. In PE question you usually have to think of a trick to get your program to get the result fast enough. In this case you need to understand why there is no need to check weather a prime is divisible by a prime that is bigger the the square root of the number.
If a number x was divisible by a prime number p that is bigger than the square root of x, that would mean that there is a natural number n that is n = x/p, if p is bigger than the square root of x then n is smaller than the square root of x (think about why this is true). That means that we would find that the number x is also divisible by the number n that is smaller than the square root of x. That means we would have already found that x is divisible by n (or a prime factor of n) when we were checking all the numbers that are smaller than the square root of x, therefor there is no need to check any number bigger then the square root of a number is order to know if it is prime Q.E.D .
This way you can save A LOT of computations. the following is a python program that implements this idea:
import math
primes = [2]
is_prime = True
# loop over all the ODD numbers from 3 to 2,000,000 (no need to check even numbers)
for number in xrange(3, 2000000 + 1, 2):
sqrt = math.sqrt(number)
# loop over all the primes we have so far
for prime in primes:
# if the number we are checking is divisible by a prime it is not prime and we can move on to the next number
if number % prime == 0:
# we set this value to false so that when we finish the loop we will be able to know if the number is prime or not
is_prime = False
break
# this line is where the clever part is, if we already checked `all the primes that are smaller than square root of x, and we did not find any primes that our number is divisible by, then we will not find any primes higher than the square root of the number that the number is divisible by`
if prime > sqrt:
break
if is_prime:
primes.append(number)
else:
is_prime = True
# we are done, print the answer
print sum(primes)
As much as I appreciate the detailed answer by #DonatPants, I believe that solution is too complicated. First, we don't need to calculate sqrt() when the simpler square will do (I.e. square both sides of the equation.) Second the order of tests seems backward, why check prime > sqrt after if number % prime == 0? If prime > sqrt, you don't need the other test. And what's with that boolean? My simpler approach to this problem:
primes = [2]
for number in range(3, 2000000 + 1, 2): # only test odd numbers
for prime in primes:
if prime * prime > number: # we're past sqrt, a prime!
primes.append(number)
break
if number % prime == 0: # a composite
break
print(sum(primes))
Redundantly computing prime * prime is an inefficiency. It doesn't make any difference for this range of numbers but if needed, you can keep a separate array of squares, enumerate the primes and use the index generated to access the square, which you save when you save the prime. Squaring just the primes is cheaper than square rooting all the numbers:
primes = [2]
squares = [4]
for number in range(3, 2000000 + 1, 2):
for index, prime in enumerate(primes):
if squares[index] > number:
primes.append(number)
squares.append(number * number)
break
if number % prime == 0:
break
print(sum(primes))
We're wasting space to avoid wasting time. But again, for this range of numbers, it's not worth it.

Python- Prime summands to an even number

This is the assignment my professor gave me. I have no idea where to start or what to do!
The point is to use loops to figure this out and I can do the loops, but this is blowing my mind.
Even numbers and primes.
A prime number is one that has 1 and itself as its only divisors. 2, 3, 5, 7 and 11 are the first several. Notice
that 'being prime' is purely a multiplicative condition -- it has nothing to do with addition. So it might be
surprising that if we start listing even numbers, they seem to be the sum (addition!) of two primes.
4 = 2 + 2, 6 = 3 + 3, 8 = 5 + 3, 10 = 3 + 7, 12 = 7 + 5, 14 = 7 + 7, 16 = 13 + 3, ...
Is this always the case? Can every even number be written as the sum of two primes?
Write a is_prime(n) function.
It should accept a positive integer n>1 as input, and output True or False, depending on whether n is or is not
a prime number. Do this with a loop that checks whether for any integer d, 1 < d < sqrt(n), d divides n.
I'd suggest a while loop -- think carefully about the conditional for the loop, and when you want to change
this conditional inside the loop. (Use a boolean for your condition).
Write a prime_sum(n) function.
It should accept an even number n>1 as input, and via a loop search for primes p & q with p + q = n.
Hint: start with p = 3. If (p) and (n-p) are prime you are done. If not, set p+=2 and try again.
Make sure you do not search forever!
Main.
Ask the user for an even number n. Continually ask them until they do give you a positive even number.
Search for the summands p & q, and either print them out (if they exist) or say they don't.
Ask the user if they wish to try with another even, and let them continue until they quit.
I didn't know I could edit this! :) So this is what I have so far. I have not tested it yet to debug it b/c I want to get it all down and when the errors pop up I will address them, but if you see any immediate problems let me know.
def is_prime(n):
d=2
while n>1 and d<n**0.5:
if n%2==0:
c=False
d+=1
return c
def prime_sum(n):
p=3
while n>1:
q=n-p
if q<=0:
p+=2
q=n-p
is_prime(q)
else:
is_prime(q)
is_prime(p)
while True:
print("The prime summands of", n, "are", p, "and", q)
while False:
print("There are no prime summands of", n)
def main():
n=eval(input("Gimme an even number please: "))
while True:
n=eval(input("That is not a positive even number. Try again: "))
#not sure how to combine yet, but I am still finishing.
#will edit again when I have it all down.
Don't worry about the big picture of the assignment being difficult. Just go step by step as the prof has broken it down.
Prime Number
A prime number (or a prime) is a
natural number that has exactly two
distinct natural number divisors: 1
and itself.
A)
def is_prime(n): # Write a is_prime(n) function.
if n <= 1: # It should accept a positive integer n>1
return False
if n == 2: # 2 has 2 divisors 1 and itself satisfying definition
return True
i = 2 # Start from 2 and check each number to the sqrt(n)
while i < n**0.5: # sqrt(n) can be written as n**0.5
if n % i == 0: # If n is divisible by i, which is not 1 or itself,
return False # return False (not prime)
i+=1 # Increment i by 1 and check looping condition
return True # If loop breaks, return True (prime)
Primes can be discovered in a variety of ways. This is one of the most basic with the only optimisation being that the divisor to check is stopped at the root of n instead of checking every number to n.
The most basic probably being:
def is_prime(n):
if n < 2:
return False
for i in range(2,n):
if n % i == 0:
return False
return True
B)
def prime_sum(n):
if n % 2 or n < 1: # if n is odd or less than 1 return invalid
return "invalid input"
p = 3
while n-p > 0:
if is_prime(p) and is_prime(n-p):
return (p, n-p) # if both conditions are met, return prime tuple
p+=2 # only check odd numbers
return "no answer found"

Calculating prime numbers

I am now doing the MIT opencourse thing, and already the second assignment, I feel it has left me out in the cold. http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/assignments/pset1a.pdf
The specifics of it, are to write something that can calculate the 1000th prime number. We only know about the print, ==, =, 1=,if, else, elif, while, %, -,+,*,/, commands I think. We also don't yet know about importing libraries.
My Idea of how it would work is to take an odd number and try to divide it by, 3,4,5,6,7,8,9 and if %n !=0, then add a number to NumberofPrimes variable starting with 11 as the base of the tests, and assigning it a base value of 4 at the base of NumberofPrimes, though I don't know if that is even right, because I wouldn't know how to display the 1000th prime number.
Am I close?
The latest incarnation of it is as follows:
##calculate the 1000th prime number
potprime = 3
numberofprime = 1
cycle = if potprime%3 = 0:
break
if potpimre%4 = 0:
break
if potprime%5 = 0:
break
if potprime%6 = 0:
break
if potprime%7 = 0:
break
if potprime%8 = 0:
break
if potprime%9 = 0:
break
numberofprime + 1
potprime + 1
if potprime%2 == 0:
potprime = potprime + 1
if potprime != 0:
cycle
Where exactly am I going wrong? Walk me through it step by step. I really want to learn it, though I feel like I am just being left out in the cold here.
At this point, it would be more beneficial for me to see how a proper one could be done rather than doing this. I have been working for 3 hours and have gotten nowhere with it. If anybody has a solution, I would be more than happy to look at it and try to learn from that.
Looks like I am late
It is quite straight forward that if a number is not divisible by any prime number, then that number is itself a prime number. You can use this fact to minimize number of divisions.
For that you need to maintain a list of prime numbers. And for each number only try to divide with prime numbers already in the list. To optimize further it you can discard all prime numbers more than square root of the number to be tested. You will need to import sqrt() function for that.
For example, if you test on 1001, try to test with 3, 5, 7, 11, 13, 17, 19, 23, 29 and 31. That should be enough. Also never try to find out if an even number is prime. So basically if you test an odd number n, then after that test next number: (n + 2)
Have tested the below code. The 1000th prime number is 7919. Not a big number!!
Code may be like:
from math import sqrt
primeList = [2]
num = 3
isPrime = 1
while len(primeList) < 1000:
sqrtNum = sqrt(num)
# test by dividing with only prime numbers
for primeNumber in primeList:
# skip testing with prime numbers greater than square root of number
if num % primeNumber == 0:
isPrime = 0
break
if primeNumber > sqrtNum:
break
if isPrime == 1:
primeList.append(num)
else:
isPrime = 1
#skip even numbers
num += 2
# print 1000th prime number
print primeList[999]
The following code is gross, but since 1000 is indeed a small index, it solves your problem in a fraction of a second (and it uses only the primitives you are supposed to know so far):
primesFound = 0
number = 1
while primesFound < 1000:
number = number + 1 # start from 2
# test for primality
divisor = 2
numberIsPrime = True
while divisor*divisor <= number: # while divisor <= sqrt(number)
if number % divisor == 0:
numberIsPrime = False
break
divisor = divisor + 1
# found one?
if numberIsPrime:
primesFound = primesFound + 1
print number
You can test the solution here.
Now you should find a more efficient solution, optimize and maybe go for the 1000000-th prime...
For one thing, I'm pretty sure that in Python, if you want to have an if statement that tests whether or not A = B, you need to use the == operator, rather then the =.
For another thing, your algorithm would consider the number 143 to be prime, even though 143 = 11 * 13
You need keep track of all the prime numbers that you have already computed - add them to an array. Use that array to determine whether or not a new number that you are testing is prime.
It seems to me that you are jumping into the deep-end after deciding the kiddy-pool is too deep. The prime number project will be assignment 2 or 3 in most beginning programming classes, just after basic syntax is covered. Rather than help you with the algorithm (there are many good ones out there) I'm going to suggest that you attempt to learn syntax with the python shell before you write long programs, since debugging a line is easier than debugging an entire program. Here is what you wrote in a way that will actually run:
count = 4
n = 10 #I'm starting you at 10 because your method
#says that 2, 3, 5, and 7 are not prime
d = [2, 3, 4, 5, 6, 7, 8, 9] #a list containing the ints you were dividing by
def cycle(n): #This is how you define a function
for i in d: #i will be each value in the list d
if not n%i: #this is equal to if n%i == 0
return 0 #not prime (well, according to this anyway)
return 1 #prime
while count < 1000:
count += cycle(n) #adds the return from cycle to count
n += 1
print n - 1
The answer is still incorrect because that is not how to test for a prime. But knowing a little syntax would at least get you that wrong answer, which is better than a lot of tracebacks.
(Also, I realize lists, for loops, and functions were not in the list of things you say you know.)
Your code for this answer can be condensed merely to this:
prime_count = 1
start_number = 2
number_to_check = 2
while prime_count <= 1000:
result = number_to_check % start_number
if result > 0:
start_number +=1
elif result == 0:
if start_number == number_to_check:
print (number_to_check)
number_to_check +=1
prime_count +=1
start_number =2
else:
number_to_check +=1
start_number = 2
To answer your subsequent question, 'How do I keep track of all the prime numbers?
One way of doing this is to make a list.
primeList = [] # initializes a list
Then, each time you test a number for whether it is prime or not, add that number to primeList
You can do this by using the 'append' function.
primeList.append( potprime ) # adds each prime number to that list
Then you will see the list filling up with numbers so after the first three primes it looks like this:
>>> primeList
[11, 13, 17]
Your math is failing you. A prime number is a number that has 2 divisors: 1 and itself. You are not testing the numbers for primality.
I am very late on this but maybe my answer will be of use to someone. I am doing the same open course at MIT and this is the solution I came up with. It returns the correct 1000th prime and the correct 100,000th prime and various others in between that I have tested. I think this is a correct solution (not the most efficient I am sure but a working solution I think).
#Initialise some variables
candidate = 1
prime_counter = 1
while prime_counter < 1000:
test = 2
candidate = candidate + 2
# While there is a remainder the number is potentially prime.
while candidate%test > 0:
test = test + 1
# No remainder and test = candidate means candidate is prime.
if candidate == test:
prime_counter = prime_counter + 1
print "The 1000th prime is: " + str(candidate)
While I was at it I went on and did the second part of the assignment. The question is posed as follows:
"There is a cute result from number theory that states that for sufficiently large n the product of the primes less than n is less than or equal to e^n and that as n grows, this becomes a tight bound (that is, the ratio of the product of the primes to e^n gets close to 1 as n grows).
Computing a product of a large number of prime numbers can result in a very large number,
which can potentially cause problems with our computation. (We will be talking about how
computers deal with numbers a bit later in the term.) So we can convert the product of a set of primes into a sum of the logarithms of the primes by applying logarithms to both parts of this conjecture. In this case, the conjecture above reduces to the claim that the sum of the
logarithms of all the primes less than n is less than n, and that as n grows, the ratio of this sum to n gets close to 1."
Here is my solution. I print the result for every 1,000th prime up to the 10,000th prime.
from math import *
#Initialise some variables
candidate = 1
prime_counter = 1
sum_logs = log(2)
while prime_counter < 10000:
test = 2
candidate = candidate + 2
# While there is a remainder the number is potentially prime.
while candidate%test > 0:
test = test + 1
# No remainder and test = candidate means candidate is prime.
if candidate == test:
prime_counter = prime_counter + 1
# If the number is prime add its log to the sum of logs.
sum_logs = sum_logs + log(candidate)
if prime_counter%1000 == 0:
# For every 1000th prime print the result.
print sum_logs," ",candidate," ",sum_logs/candidate
print "The 10000th prime is: " + str(candidate)
Cheers,
Adrian
I came up with this solution in my interview, but I didn't get the job :( It has about 1/100 less iterations than the solution above:
from math import *
MAX_IDX=1000
MAX_IDX-=1
num_iter=0
l_pirme_list=[3]
candidate=l_pirme_list[0]
prime_counter=1
while prime_counter < MAX_IDX:
candidate+=2
#Cut the binary number in half. This is quite faster than sqrt()
bin_candidate=format(candidate, "2b")
max_prime_search=int(bin_candidate[:len(bin_candidate)/2+1],2)+1
# max_prime_search=sqrt(candidate)+1
candidate_is_prime=1
for prime_item in l_pirme_list:
num_iter+=1
if candidate % prime_item==0:
candidate_is_prime=0
break
elif prime_item > max_prime_search:
candidate_is_prime=1
break
if candidate_is_prime:
prime_counter+=1
l_pirme_list.append(candidate)
l_pirme_list.insert(0,2)
print "number iterations=", num_iter
print l_pirme_list[MAX_IDX]

Categories