Finding prime numbers < n - python

I'm working on Project Euler, problem 3.
The problem is:
"The prime factors of 13195 are 5, 7, 13 and 29. What is the largest
prime factor of the number 600851475143?"
In answering this question, I'm breaking down the task to first find all prime numbers < x (in reverse). Why does the following code not seem to work, I'm not sure if it is the logic or incorrect use of operator.
#A function to find prime numbers under n
def find_prime(n):
for i in reversed(xrange(2, n)):
if (n % i) != 0:
print i
find_prime(n)
In testing, I also built a prime number checker for fun, so I have tested somewhat.
def prime_checker(n):
if n > 2:
for i in range (2,n):
if (n % i) == 0:
print "%s is not a prime number" % (n)
break
else:
print "%s is a prime number" % (n)
Can anyone help me understand what I'm doing wrong with the find_prime() function before I move on to the next step that I will use to solve the problem?

Before you start coding, maybe you should read up a bit on what you are dealing with. Primes are well studied. First of all, you do not need all the primes < x. Secondly, every time you find a divisor, you can divide the number by that and have a smaller problem on your hands. In the end, the number that will be left will be what you are looking for. Now, except for 2, no other even numbers are primes, so xrange(3, n, 2). Search some more and you'll find a solution that won't need the time of the universe to finish.

You can't tell whether a number is prime until you make it all the way through the loop without finding any divisors. You're reporting that a number is prime as soon as you find a number that doesn't divide it, but it might still be divisible by some higher number. Your code will say that all odd numbers are prime, because they aren't a multiple of 2.
Also, it's not necessary to go all the way to n in your range. None of the factors of a number can be greater than the square root of the number.
def prime_checker(n):
if n > 2:
for i in range (2, int(n ** .5)+1):
if (n % i) == 0:
print "%s is not a prime number" % (n)
return false
print "%s is a prime number" % (n)
return true

Related

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

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.

Right algorithm for finding largest prime factor

I am trying to find out the largest prime factor of any number. I am doing the program for this problem in python, but there seems to be something wrong with the algorithm that I am following. It seems to fall into an infinite loop. The program goes like this:
def prime(n):
i=0;
while(n!=2):
for i in range(2,n):
if(n%i==0):
prime(n/i);
else:
continue;
print("The highest prime factor is: "),n;
print("Enter a number to find its highest prime factor");
n=input();
prime(n);
Just point out what are the problems here and also mention if there are any other better algorithm than this one for solving this.
EDIT : It feels like I can't manage to be clear without some code, so here it is, with a few modification from yours :
def prime(n):
i=2
while (n%i != 0 and i < n):
i += 1
if (i < n):
return prime (n/i)
else:
print("The highest prime factor is: "),n
print("Enter a number to find its highest prime factor")
n=input()
prime(n)
However, your algorithm is not very efficient. For example, you might consider using Pollard's Rho if you want something better and not long to code.
And even if you want to stick with your idea, you shouldn't do your divisibility tests like this. You may want to run an Erathostene sieve first to only test divisibility by prime factors. Or even only remember the last divisor you found in order to restart the algorithm from there, not from 2.
For example, a little bit better code would be :
def prime(n,a):
i = a
while (n%i != 0 and i*i < n):
i += 1
if (i*i < n):
return prime (n/i, i)
else:
print("The highest prime factor is: "),n
print("Enter a number to find its highest prime factor")
n=input()
prime(n,2)
My solution is rather simple and deals well with huge numbers that would cause memory error in most of the solutions above.
import math
def prime(n):
for x in range(2, int(math.sqrt(n)) + 1):
if n % x == 0:
print n / x
return prime(n / x)
if __name__ == '__main__':
prime(898563214300)
The last printed number is the largest prime factor.
Avoiding recursive calls:
def largest_prime_factor(number):
if number == 1:
return 1
test = 2
while number > 1:
if number % test == 0:
number /= test
else:
test += 1
return test
One simple (but highly inefficient) approach without recursion would be:
(please excuse my python syntax).
Assuming isPrime(k) is a function that returns true if k is prime. It can be implemented using sieve of Erastosenes.
def prime(n):
i=0;
largestPrimeFactor = -1;
for i in range(2,n/2):
if( isPrime(i) && n%i==0 ) :
largestPrimeFactor = i;
print("The highest prime factor is: "),largestPrimeFactor
I can stop your code getting tuck in a loop as follows.
The main problem with the stuck in a loop is the while(n!=2) (or 1 or whatever) is that you don't change n.
Note - it still won't give you prime numbers
def prime(n):
i=0
if(n==2):
print "The highest prime factor is 2"
return
for i in range(2,n):
if(n%i==0):
prime(n/i)
else:
continue
print("The highest prime factor is: "),n
print("Enter a number to find its highest prime factor");
n=input()
prime(n)
Search SO with '[python] primes' for lots of ways to do this properly.
consider this code snippet in C, this is a very efficient algorithm for finding the largest prime factor of a number.
The functions are self-explanatory.
int isPrime(long long int n)
{
long long int i;
for(i=2;i*i<=n;i++)
if(n%i==0)
return 0;
return 1;
}
long long int findLargestPrimeFactor(long long int n)
{
long long int counter=2;
while(n!=1)
{
if(isPrime(n))
return n;
while(n%counter==0)
n/=counter;
counter++;
}
return counter-1;
}
The code can be further optimized as shown below, its written in php but the logic seems fair
for($div=2;$div<=sqrt($n);$div++)
{
if($n%$div==0)
{
$n = $n/$div;
$div--;
}
}
by taking the sq root , you avoid the uncecessary looping.

Determining whether a number is prime or not

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

Categories