Python Script Not Finishing - python

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.

Related

Belphegor prime number problem with Python

I have seen a video about Belphegor prime numbers. The definition of a Belphegor prime is one such that in the expression (10^(n+3)+666)*(10^(n+1)+1) is prime for n being a positive integer.
I tried making a Python program that would determine whether an input number n will produce a prime number in the expression mentioned before but my code said that for all n in the expression would be prime which is not true and it said it indefinitely.
My code:
n = int(input("Enter a positive number n: "))
x =(10**(n+3)+666)*10**(n+1)+1
for i in range(2,x - 1):
if x % i == 0:
print("Composite")
else:
print("Belphegor prime")
Please help me fix this error!
Your problem is that your code prints out either Composite or Prime on every iteration through the loop. Instead, you need to assume the number is prime and if at any time the test fails, set a flag to false; then use the state of the flag at the end of the loop to determine if the number is actually prime:
from math import sqrt
n = int(input("Enter a positive number n: "))
x =(10**(n+3)+666)*(10**(n+1)+1)
p = True
for i in range(2,int(sqrt(x))+1):
if x % i == 0:
p = False
break
if p:
print("Belphegor prime")
else:
print("Composite")
Note you can shorten your loop by only iterating as far as sqrt(x) as any number greater than sqrt(x) which is a divisor of x will have a matching divisor less than sqrt(x).
Note also that as #LeoE pointed out in the comments to your question, you are missing some () in your computation of x.

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)

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.

Finding prime numbers < n

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

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