Project Euler #3 with Python (Followup) - python

I'm working on problem #3 on project euler, and I've run into a problem. It seems that the program is copying all the items from factors into prime_factors, instead of just the prime numbers. I assume this is because my is_prime function is not working properly. How can I make the function do what I want? Also, in the code, there is a line that I commented out. Do I need that line, or is it unnecessary? Finally, is the code as a whole sound (other than is_prime), or is it faulty?
The project euler question is: The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 600851475143 ?
A link to a previous question of mine on the same topic: https://stackoverflow.com/questions/24462105/project-euler-3-python?noredirect=1#comment37857323_24462105
thanks
import math
factors = []
prime_factors = []
def is_prime (x):
counter = 0
if x == 1:
return False
elif x == 2:
return True
for item in range (2, int(x)):
if int(x) % item == 0:
return False
else:
return True
number = int(input("Enter a number: "))
start = int(math.sqrt(number))
for item in range(2, start + 1):
if number % item == 0:
factors.append(item)
#factors.append(number/item) do i need this line?
for item in factors:
if is_prime(item) == True:
prime_factors.append(item)
print(prime_factors)

Yes, you need the commented line.
(It seems that on that case it's not necessary, but with other numbers the part of your code for getting factors would go wrong).
Check these references:
Prime numbers
Integer factorization
Why do we check up to the square root of a prime number to determine if it is prime or not
I got a very fast result on my computer with the following code:
#!/usr/bin/env python
import math
def square_root_as_int(x):
return int(math.sqrt(x))
def is_prime(number):
if number == 1:
return False
for x in range(2, square_root_as_int(number) + 1):
if x == number:
next
if number % x == 0:
return False
return True
def factors_of_(number):
factors = []
for x in range(2, square_root_as_int(number) + 1):
if number % x == 0:
factors.append(x)
factors.append(number/x)
return factors
factors = factors_of_(600851475143)
primes = []
for factor in factors:
if is_prime(factor):
primes.append(factor)
print max(primes)
# Bonus: "functional way"
print max(filter(lambda x: is_prime(x), factors_of_(600851475143)))

Your is_prime() returns early. Here's a fixed version:
def is_prime (x):
if x == 1:
return False
if x == 2:
return True
for item in range (2, int(x)):
if int(x) % item == 0:
return False
return True

you should not be using int(x) in the way that you currently are. i know you're forcing the int type because you want to convert from string input, but this will also allow the user to enter a float (decimal), and have it interpreted as either prime or not. that is bad behavior for the function. see my solution below. if you use eval to verify the input, you can just use x later, in place of int(x).
import math
factors = []
prime_factors = []
def is_prime (x):
x = eval(x) # this will cause a string like '5' to be evaluated as an integer.
# '5.2' will be evaluated as a float, on the other hand.
if type(x) != int:
raise Exception('Please enter an integer.') #prevents bad input
counter = 0 #this counter is not used. why is it initialized here?
if x == 1:
return False
elif x == 2:
return True
for item in range (2, x):
if x % item == 0:
return False
else:
return True

Use the while loop. n%i simply means n%i!=0
i = 2
n = 600851475143
while i*i <= n:
if n%i:
i+=1
else:
n //= i
print n

Related

Next Prime Number in Python

I'm a beginner in Python and I'm practicing to code this problem I saw. Next prime is needed, but there are limitations on the input. I have searched for similar questions, but my code is still not working. Hope you can help. Thank you!
The problem I get is when I enter 32, the results show 33 when the next prime is 37...
Here's my code so far.
num = int(input("Enter a positive number:"))
import math
def nextprime(n):
if n < 0:
raise ValueError
for next in range(n + 1, n +200):
if next > 1:
for i in range(2, next):
if (next % i) == 0:
break
else:
return next
In your code when you arrive to a number that reminder is not zero you return that number. You need a flag for every number this flag is True if can be divide flag convert to False for the first number that flag not convert to false return that number like below.
Don't use next because this is a builtin function.
Try this: (I don't improve your code)
def nextprime(n):
if n < 0:
raise ValueError
for i in range(n + 1, n +200):
if i > 1:
pr = True
for j in range(2, i):
if (i % j) == 0:
pr = False
break
if pr:
return i
return 'not found'
You can also try this code, write function to check that a number is prime or not like def is_prime then for number of larger that you input num find min number next. (this answer from this thread.)
def is_prime(x):
return all(x % i for i in range(2, x))
def next_prime(x):
return min([a for a in range(x+1, 2*x) if is_prime(a)])
print(next_prime(32))
You can also use sympy like below: (this answer from this thread.)
from sympy import *
nextprime(32)
def next_prime(n):
while True:
n=n+1
for i in range (2,int(n/2)):
if n%i==0:
break
else:
return n
print(next_prime(67))
Few off-topic tips:
as user1740577 mentioned, don't use next as a variable name
refrain from using eval when possible, it's okay here, but in real project this will lead to big no-no.
Place imports at the very top of your script
Consider using variable names i and j only for iterations.
For duplicate except blocks use (Error, Error)
As for solution to your problem, with some adjustments, if you don't mind
def next_prime(n: int) -> int:
if n < 0:
raise ValueError('Negative numbers can not be primes')
# Base case
if n <= 1:
return 2
# For i as every odd number between n + 1 and n + 200
for i in range(n + 1 + (n % 2), n + 200, 2):
# For every odd number from 3 to i (3 because we covered base case)
for j in range(3, i, 2):
# If remained is equals to 0
if not i % j:
# break current loop
break
# If loop j didn't break [nobreak: ]
else:
return i
raise RuntimeError('Failed to compute next prime number :c')
def main():
while True:
try:
num = int(input('Enter positive number: '))
print(f'Next prime is: {next_prime(num)}')
break
except ValueError:
print('Please enter a positive integer!')
if __name__ == '__main__':
main()
Made some speed improvements to the code from #rajendra-kumbar:
#!/usr/bin/env python
import sys
import time
import math
def next_prime(number):
if number < 0:
raise ValueError('Negative numbers can not be primes')
# Base case
if number <= 1:
return 2
# if even go back 1
if number % 2 == 0:
number -= 1
while True:
# only odds
number += 2
#only need to check up to and including the sqrt
max_check = int(math.sqrt(number))+2
# don't need to check even numbers
for divider in range(3, max_check, 2):
# if 'divider' divides 'number', then 'number' is not prime
if number % divider == 0:
break
# if the for loop didn't break, then 'number' is prime
else:
return number
if __name__ == '__main__':
number = int(sys.argv[1].strip())
t0 = time.time()
print('{0:d} is the next prime from {1:d}'.format(next_prime(number), number))
run_time = time.time() - t0
print('run_time = {0:.8f}'.format(run_time))
it is about twice as fast
You can try something like simple:
def is_prime(number:int):
check = 0
for i in range(2,number):
if number % i == 0:
check += 1
if check == 0:
return True
else:
return False
def next_prime(value):
check = value + 1
while is_prime(check) is False:
check += 1
return check
value = int(input("Insert the number: "))
print(next_prime(value))

Find the next prime number in Python

I have a function that takes a number (for example, 5) and returns the first prime number after the input number (in this case, it would be 7).
This is my code:
def prime(n):
np=[]
isprime=[]
for i in range (n+1,n+200):
np.append(i)
for x in range(2,199):
for j in np:
if x%j!=0:
isprime.append(x)
return min(isprime)
However, this code doesn't work (it always returns 2). Where is the mistake?
You have a few mistakes, most notably np is clearly meant to be the potential primes (it starts at n+1 which is the first potential number that fits your critera "the first prime number after the input number"), and yet you add x to your prime list, which is from range(2,199), you should be using:
isprime.append(j)
Your primality test is also the wrong way round as a result, you should be using:
j % x != 0
Lastly, you can't append a number if that condition is true in one case, it has to be true in all cases (where x is an integer which satisfies 2 <= x < j), because of this you should switch your second set of for loops around (the x loop should be the inner loop), and you should also only loop up to j-1 (the number being tested). Additionally, you should instead choose to not add an item if j % x == 0:
for ...:
val_is_prime = True
for ...:
if j % x == 0:
val_is_prime = False
break
if val_is_prime:
isprime.append(j)
This results in the following code:
def prime(n):
np=[]
isprime=[]
for i in range (n+1,n+200):
np.append(i)
for j in np:
val_is_prime = True
for x in range(2,j-1):
if j % x == 0:
val_is_prime = False
break
if val_is_prime:
isprime.append(j)
return min(isprime)
And test run:
>>> prime(5)
7
>>> prime(13)
17
>>> prime(23)
29
Note that there's several other efficiency improvements that could be made, but this answer focuses on the mistakes rather than improvements
Try this one, the most pythonic and clear way to do this that I found (but probably not the most efficient):
def is_prime(x):
return all(x % i for i in range(2, x))
def next_prime(x):
return min([a for a in range(x+1, 2*x) if is_prime(a)])
print(next_prime(9))
https://www.geeksforgeeks.org/python-simpy-nextprime-method/
from sympy import *
# calling nextprime function on differnet numbers
nextprime(7)
nextprime(13)
nextprime(2)
Output:
11 17 3
This code working.
def prime(n):
next_prime = n + 1
prime = True
while True:
for i in range(2, next_prime):
if next_prime%i ==0:
prime = False
break
if prime:
return next_prime
else:
next_prime = next_prime + 1
if next_prime % 2 == 0:
next_prime = next_prime + 1
prime = True
if __name__=="__main__":
print(prime(5))
Here is one working sample.
inputNumber = int(input("Enter number to find next prime: "))
def nextPrime(inputNum):
for nextNumToChk in range(inputNum+1, inputNum +200):
if nextNumToChk > 1:
# If num is divisible by any number between 2 and val, it is not prime
for i in range(2, nextNumToChk):
if (nextNumToChk % i) == 0:
break
else:
#found the prime
return nextNumToChk
result = nextPrime(inputNumber)
print "Next Prime is : ",result
Output:-
Enter number to find next prime: 5
Next Prime is : 7
def is_prime(n):
# Corner case
if n <= 1:
return False
# Check from 2 to n-1
for i in range(2, n):
if n % i == 0:
return False
return True
def first_prime_over(n):
prime_number = (i for i in range(n) if is_prime(i))
try:
for i in range(0,n):
(next(prime_number))
except StopIteration:
prime_number_next = (i for i in range(n,n+1000) if is_prime(i))
print(next(prime_number_next))
first_prime_over(10)
Try this one:
def find_next_prime(n):
return find_prime_in_range(n, 2*n)
def find_prime_in_range(a, b):
for c in range(a, b):
for i in range(2, c):
if c % i == 0:
break
else:
return c
return None
def main():
n = int(input('Find the next prime number from: '))
print(find_next_prime(n+1))
if __name__ == '__main__':
main()
n = int(input("Enter a number"))
while True:
n+=1
for x in range(2,n):
if n%x==0:
break
else:
print("next prime number is",n)
break

how to find a prime number function in python

I started getting back to python coding and realized I couldn't quite figure this out. I'm trying to code a prime number function. Could someone help with this?
Here is my code:
def is_prime(x):
a = True
for n in range(2, x-1):
while n < x:
n+=1
if x % n == 0:
a = False
elif n < 2:
a = False
else:
a = True
break
break
return a
If anyone has an idea on what I'm doing wrong, please let me know. A month ago I tried this and couldn't get the logic down. I think I was stumped and didn't ever ask for help... Also, how long do you think I should try to do this for before I ask for help on average?
As, it has been said, you can optimize the code by just checking the odd numbers and iterating upto the sqrt of the num
import math
def isPrime(num):
if(num==1):
return False
if(num==2):
return True
if(num%2==0):
return False
i = 3
while(i<math.sqrt(num)+1):
if num%i==0:
return False
i += 2
return True
#do the inputs and check if isPrime
#print(isPrime(2))
using your code, and focusing on code structure:
def is_prime(x):
# function contents must be indented
if x == 0:
return False
elif x == 1:
return False
# your base cases need to check X, not n, and move them out of the loop
elif x == 2:
return True
for n in range(3, x-1):
if x % n == 0:
return False
# only return true once you've checked ALL the numbers(for loop done)
return True
adding some optimizations:
def is_prime(x):
if x <= 1:
return False
if x == 2:
return True
for n in range(3, x**(0.5)+1, 2): # this skips even numbers and only checks up to sqrt(x)
if x % n == 0:
return False
return True
def prime(number):
for i in range(2,number,1):
if number % i == 0:
return False
return True
entry = int(input("Please enter the number: "))
while True:
if prime(entry):
print ("It's a prime number. ")
continue
else:
print ("It's not a prime number.. ")
continue
You will entry a number then this function will give you if its a prime or not. Check the function it will solve your problem.
ALSO You can upgrade the speed of your program. You know prime numbers can not be even, so you you dont have to check even numbers
like 4-6-8-26. So in the range function, which is (2,number) add "2"
end of it. like (3,number,2) then program will not check even numbers.
ALSO a factor can not be bigger than that numbers square root. So you dont have to check all of numbers till your main number, its
enough to check your numbers square root. like: (2,number**0.5) that
means from 2 to your number square root. So double up for program
speed.
So the function will be:
def prime(number):
for i in range(3,(number**0.5)+1),2):
if number % i == 0:
return False
return True
The first function enough for you actually. I am working with huge numbers, so I have to upgrade the speed of my program.
def is_prime(x):
for n in range(2, x-1):
if n == 0:
return False
elif n == 1:
return False
elif n == 2:
return True
elif x % n == 0:
return False
else:
return True
What you are doing wrong is , the first three if elif blocks are executed every time in the loop. So, they should be outside the for loop. Also.
if x%n==0:
return True
It is fine. But the later
else:
return True
is wrong because whenever the first n does not divide the x, it will return Composite. So,
return True
block must be outside the for loop.
Other optimizations can be done by yourself.
This is how I solved it
def is_prime(n):
if n==1:
print("It's not a Prime number")
for z in range(2,int(n/2)):
if n%z==0:
print("It's not a Prime number")
break
else:
print("It's a prime number")
or if you want to return a boolean value
def is_prime(n):
if n==1:
return False
for z in range(2,int(n/2)):
if n%z==0:
return False
break
else:
return True

python check prime, stuck at one point

This was the question our teacher gave us:
"One way to determine whether or not a number is a prime number is as follows:
if the number < 2, then return False
if the number is 2, then return True
for each value of i, where i >=2 and i < number:
if i divides the number evenly, then return False
return True"
I've managed to work through most of it, but was stuck when it said 'for each value of i, where i >=2 and i < number:'
how do I write this in code?
if number < 2:
return False
if number == 2:
return True
?????????
if i%2 == 0:
return False
return True
Yo need a loop to check all numbers from 2 to one less than the number being checked. There are better ways to do it (such as only checking up to the square root of the number) but a simplistic algorithm would be:
def isPrime (n):
if n < 2:
return False
for x in range (2, n):
if n % x == 0:
return False
return True
So, in terms of what you need to add to your code:
a loop iterating some variable from two up to one less than the number.
checking modulo with that variable rather than the hard-coded 2.
You will need to start a loop from 2 to the number
for i in range(2,number)
if number%i == 0:
return false
def isprime(num):
#this is the part you are missing
for divider in range(2,num):
if num%divider == 0:
return False
#end of missing part
return not num%2 == 0 or num==2 or num==0
for i in range(0,200):
if isprime(i): print i, isprime(i)

python - returning values for which if statement is true

I am starting out in Python and have a question about the following piece of code:
def prime2(n):
n = eval(input("What is your number? "))
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
else:
return True
So when True is returned, n is prime. Now is there a way to list all the values of n for which the if statement is true?
Since there is an infinite amount of prime numbers, no. However, you can list all primes in a certain interval:
foo = [x for x in range(1000) if prime2(x)]
This gives you a list of all primes in the interval 0 to 1000.
Edit: Why do you have n as parameter to your function, and then read it as input from the user? This discards the argument that was passed to the function. Input from the user should be outside of that function. The script could look like this:
def prime2(n):
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
max = int(input("What is your number? "))
print [x for x in range(max) if prime2(x)]
Edit2: Fixed the code of prime2 according to #rmflow's comment to the question.
if you need a list of all values when n is a prime then you need a prime number generator. An example (not effectuve though) based on your prime2 function:
import math
def prime2(n):
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
def prime_generator():
n = 1
while True:
n += 2
if prime2(n):
yield n
primes = prime_generator()
for prime in primes:
print prime
will print prime numbers until break

Categories

Resources