I am trying to write a program that will print all the primes within a given range. I have written it, the output is almost okay, it prints primes, but for some reason it prints 4, which is not a prime...
Any assistant will be most appreciated !
def primes():
start = int(input("Enter the starting number: "))
end = int(input("Enter the ending number: "))
num = 0
i = 0
ctr = 0
for num in range(start,end+1,1):
ctr = 0
for i in range(2,num//2,1):
if num % i == 0 :
ctr = ctr + 1
break
if (ctr==0 and num != 1):
print(num)
for i in range(2,num//2,1):
Lets check this snippet of code when num = 4,it becomes
for i in range(2,2,1):
Now we see the problem.
Solution..?
for i in range(2,(num//2)+1,1):
The following methods are all possible prime checkers you might use to check within your range:
def isPrime(Number): # slow
return 2 in [Number, 2 ** Number % Number]
def isprime(n): # out of memory errors with big numbers
"""check if integer n is a prime"""
# make sure n is a positive integer
n = abs(int(n))
# 0 and 1 are not primes
if n < 2:
return False
# 2 is the only even prime number
if n == 2:
return True
# all other even numbers are not primes
if not n & 1:
return False
# range starts with 3 and only needs to go up the squareroot of n
# for all odd numbers
for x in range(3, int(n ** 0.5) + 1, 2):
if n % x == 0:
return False
return True
def is_prime(n): # Best until now
if n == 2 or n == 3:
return True
if n < 2 or n % 2 == 0:
return False
if n < 9:
return True
if n % 3 == 0:
return False
r = int(n ** 0.5)
f = 5
while f <= r:
# print '\t', f
if n % f == 0:
return False
if n % (f + 2) == 0:
return False
f += 6
return True
for i in range(2,num//2,1):
Above line is wrong. You are iterating from 2 to num / 2 - 1.
You should iterate from 2 to sqrt(num). (range(2, int(math.sqrt(n)) + 1))
Alternatively you can do a special check for 2 and modify your range to range(3, int(math.sqrt(n) + 1, 2)
Related
def sumPrimes(num):
sum = 0
if num>1:
for i in range(1, num):
if num % i == 0:
pass
else: sum = sum + i
return sum
print(sumPrimes(3))
i don't know why this isnt working pls help. I am trying to find the sum of all the prime numbers below a certain number. if the initial number is prime we return it.
Meaby It will help u
# Program to check if a number is prime or not
num = 407
# To take input from the user
#num = int(input("Enter a number: "))
# prime numbers are greater than 1
if num > 1:
# check for factors
for i in range(2,num):
if (num % i) == 0:
print(num,"is not a prime number")
print(i,"times",num//i,"is",num)
break
else:
print(num,"is a prime number")
# if input number is less than
# or equal to 1, it is not prime
else:
print(num,"is not a prime number")
If you want to do this efficiently it's more complex than you might have imagined.
def genprime():
yield 2
D = {4:[2]}
q = 3
while True:
if q not in D:
yield q
D[q * q] = [q]
else:
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 2
def isprime(n):
if isinstance(n, int) and n >= 2:
g = genprime()
s = int(n ** 0.5)
while True:
d = next(g)
if d > s:
return True
if n % d == 0:
break
return False
def sumPrimes(n):
if isprime(n):
return n
g = genprime()
sum = 0
while (np := next(g)) < n:
sum += np
return sum
print(sumPrimes(12))
You'll need Python 3.7+ for this
This seems to work. If you want it to add 1 as a prime number change the second range to include 1.
def sumPrimes(num):
sum = 0
if num > 1:
if all(num % n for n in range(2, num)) == True: #check of prime
return num
else:
for i in range(2, num):
if all(i % n for n in range(2, i)) == True: #if you want it to add the number 1 as a prime number change this range to range(1,i)
sum += i
else:
continue
return sum
You can use is_prime to check if the number is prime in the loop:
import math
def is_prime(x):
for num in range(2, int(math.sqrt(x)) + 1):
if x % num == 0:
return False
return True
def sumPrimes(num):
return sum([x for x in range(2,num) if is_prime(x)])
I'm learning Python by doing Project Euler questions and am stuck on Problem #3.
I think I've found a solution that works, but when inserting the large number 600851475143 it just doesn't return anything. I believe that it just loads and loads cause even with 6008514 it takes 10 secs to return the answer.
# What is the largest prime factor of the number x?
import math
def isPrime(x):
try:
sqr = math.sqrt(x)
if x == 0 or x == 1:
return 0
for n in range (2 , int(sqr)+1):
if x % n == 0:
return 0
return 1
except:
return 'Give positive numbers.'
def largestPrimeFactor(x):
if isPrime(x) == 1:
return 'This number is prime.'
else:
largest = -1
mid = x/2
for n in range(2,int(mid)+1):
if isPrime(n):
if x % n == 0:
largest = n
if largest == -1:
return 'Enter numbers above 1.'
else:
return largest
print(largestPrimeFactor(600851475143))
This code should work:
import math
def isPrime(x):
try:
sqr = math.sqrt(x)
if x == 0 or x == 1:
return 0
n = 2
highest = x
while n < highest:
if x%n ==0:
return 0
highest = x/ n
n +=1
return 1
except:
return 'Give positive numbers.'
def largestPrimeFactor(x):
if isPrime(x) == 1:
return 'This number is prime.'
n = 2
highest = x
largest = 1
while n < highest:
if x%n == 0:
if isPrime(n):
largest = n
highest = x/n
n +=1
return largest
print(largestPrimeFactor(600851475143))
I made an optimization:
you check if every number is a factor of x while if for example 2 is not a factor of x for sure the maximum factor of x can be x/2. Hence if n is not a factor of x the maximum possible factor of x can just be x/n.
The code for large numbers just takes really long time, as pointed out by comments. I report other bugs.
Bug 1. Inappropriate use of try/except clause. It is recommended that try contains a single command and except catches the error. PEP8 also recommends specifying the type of error. Moreover, for your function, the error is never raised.
Bug 2. Redundancy. If x is not prime, you call isPrime for each value (let's call it i) from 2 to x/2. isPrime cycles for each number from 2 to sqrt(i). Therefore, isPrime(i) takes O(sqrt(i)) time, and we call it for i from 2 to x/2. Roughly, its running time is about O(x^(3/2)). Even if don't know a more optimal approach, this approach asks for memoization.
i have another way:
def Largest_Prime_Factor(n):
prime_factor = 1
i = 2
while i <= n / i:
if n % i == 0:
prime_factor = i
n /= i
else:
i += 1
if prime_factor < n:
prime_factor = n
return prime_factor
it faster than previous
try it:
import math
def maxPrimeFactors (n):
maxPrime = -1
while n % 2 == 0:
maxPrime = 2
n >>= 1
for i in range(3, int(math.sqrt(n)) + 1, 2):
while n % i == 0:
maxPrime = i
n = n / i
if n > 2:
maxPrime = n
return int(maxPrime)
n = 600851475143
print(maxPrimeFactors(n))
A semi-prime number is a number that can be expressed a product of two prime numbers. Example: 55 = 5 * 11
I'm trying to code a Python program that checks whether a number can be expressed as a sum of two semi-prime numbers (not necessarily distinct).
Example 1:
Input: 30
Output: Yes
Explanation: 30 can be expressed as 15 + 15, where 15 is a semi-prime number as it is a product of two prime numbers, 5 * 3.
Example 2:
Input: 62
Output: No
Explanation: Although, 62 is itself a semi-prime number (31 * 2), however, it cannot be expressed as sum of two semi-prime numbers.
Here is what I tried to do, but it doesn't work in all cases.
MAX = 200
arr = []
sprime = [False] * (MAX)
def computeSP():
for i in range(2,MAX):
cnt,num,j = 0,i,2
while (cnt<2 and j*j <= num):
while(num % j == 0):
num = int(num/j)
cnt = cnt + 1
j = j+1
if(num > 1):
cnt = cnt + 1
if(cnt == 2):
sprime[i] = True
arr.append(i)
def checkSP(n):
i = 0
while(arr[i] <= n/2):
if(sprime[n - arr[i]]):
return True
i = i+1
return False
computeSP()
n = int(input())
if(checkSP(n)):
print('Yes',end='')
else:
print('No',end='')
62 as in the case you mentioned can be expressed as sum of 2 semi primes which is 58 and 4 i.e. 62 = 58+4
58 can be expressed as factors of 29,2 (prime numbers)
4 can be expressed as factors of 2,2 (prime numbers)
Hence, answer to your question is your logic is wrong because 62 can also be expressed in the similar way.
If you want the code then here you go:
import math
def factors(n):
bool = False
for i in range(2, n):
if n % i == 0:
a = i
b = int(n / a)
if prime_number(a) and prime_number(b):
print("factors of ",n,"is",a,b)
bool = True
break
return bool
def prime_number(m):
prime = True
for i in range(3, m):
if m % i == 0:
prime = False
break
return prime
if __name__ == '__main__':
num = int(input())
z = math.ceil(num/2)
a = "NO"
for i in range(1, z):
x = i
y = num - i
if factors(x) and factors(y):
print("diff x,y=", x, y)
a = "YES"
break
print(a)
Write a recursive algorithm which enumerates dominant primes. Your algorithm should print dominant primes as it finds them (rather than at the end).By default we limit the dominant primes we are looking for to a maximum value of 10^12, the expected run time should be around or less than a minute.
The following is my python code which doesn't work as expected:
import math
def test_prime(n):
k = 2
maxk = int(math.sqrt(n))
while k <= maxk:
if n % k == 0:
return False
if k == 2:
k += 1
else:
k += 2
return (n is not 1)
def dominant_prime_finder(maxprime=10**12,n=1):
l = 1 #length of the current number
while n // 10 > 0:
l += 1
n //= 10
if test_prime(n) == True:
is_dominant_prime = True
index_smaller = n
while l > 1 and index_smaller > 9:
index_smaller //= 10
if test_prime(index_smaller) == False:
is_dominant_prime = False
break
for i in range(1,10):
if test_prime(i*10**l + n) == True:
is_dominant_prime = False
break
if is_dominant_prime == True:
print(n)
while n <= maxprime:
dominant_prime_finder()
You can solve the problem without enumerating all the numbers under 10^12 which is inefficient by doing a recursion on the length of the number.
It works the following way:
The prime number of length 1 are: 2,3,5,7.
For all these numbers check the third condition, for any digit dn+1∈{1,…,9} , dn+1dn…d0 is not prime. For 2 it's okay. For 3 it fails (13 for instance). Store all the prime you find in a list L. Do this for all the prime of length 1.
In L you now have all the prime number of length 2 with a prime as first digit, thus you have all the candidates for dominant prime of length 2
Doing this recursively gets you all the dominant prime, in python:
def test_prime(n):
k = 2
maxk = int(math.sqrt(n))
while k <= maxk:
if n % k == 0:
return False
if k == 2:
k += 1
else:
k += 2
return (n is not 1)
def check_add_digit(number,length):
res = []
for i in range(1,10):
if test_prime( i*10**(length) + number ):
res.append(i*10**(length) + number)
return res
def one_step(list_prime,length):
## Under 10^12
if length > 12:
return None
for prime in list_prime:
res = check_add_digit(prime,length)
if len(res) == 0:
#We have a dominant prime stop
print(prime)
else:
#We do not have a dominant prime but a list of candidates for length +1
one_step(res,length+1)
one_step([2,3,5,7], length=1)
This works in under a minute on my machine.
Well, there are several issues with this code:
You modify the original n at the beginning (n //= 10). This basically causes n to always be one digit. Use another variable instead:
m = n
while m // 10 > 0:
l += 1
m //= 10
Your recursive call doesn't update n, so you enter an infinite loop:
while n <= maxprime:
dominant_prime_finder()
Replace with:
if n <= maxprime:
dominant_prime_finder(maxprime, n + 1)
Even after fixing these issues, you'll cause a stack overflow simply because the dominant prime numbers are very far apart (2, 5, 3733, 59399...). So instead of using a recursive approach, use, for example, a generator:
def dominant_prime_finder(n=1):
while True:
l = 1 #length of the current number
m = n
while m // 10 > 0:
l += 1
m //= 10
if test_prime(n):
is_dominant_prime = True
index_smaller = n
while l > 1 and index_smaller > 9:
index_smaller //= 10
if not test_prime(index_smaller):
is_dominant_prime = False
break
for i in range(1,10):
if test_prime(i*10**l + n):
is_dominant_prime = False
break
if is_dominant_prime:
yield n
n = n + 1
g = dominant_prime_finder()
for i in range(1, 10): # find first 10 dominant primes
print(g.next())
This problem is cool. Here's how we can elaborate the recurrence:
def dominant_prime_finder(maxprime=10**12):
def f(n):
if n > maxprime:
return
is_dominant = True
power = 10**(math.floor(math.log(n, 10)) + 1)
for d in xrange(1, 10):
candidate = d * power + n
if test_prime(candidate):
f(candidate)
is_dominant = False
if is_dominant:
print int(n)
for i in [2,3,5,7]:
f(i)
f=0
c=1
n=raw_input("Enter the value of n")
while c<n:
for i in range(2,100):
for j in range(1,i):
if i%j == 0:
f =f+1
if f == 1:
print i
c = c+1
f = 0
If n is 5 then the output should print the first 5 prime numbers.
2,3,5,7,11
You have a few mistakes. You do not parse n as integer, you have an unnecessary loop, you inistailise c with a wrong value.
Here is a corrected version
c = 0
n=int(raw_input("Enter the value of n"))
i = 2
while True:
for j in range(2,i):
if i % j == 0:
break
else:
print i
c = c + 1
if c == n:
break
i += 1
Copy of answer to this question.
You're only checking the value of count at the end of the for loop so you will always end up with the full range of 1-100 being tested. Why is the range limited to 100?
You don't need a for loop at all. Use the while loop to keep finding primes until you have num of them.
Try something like:
import math
def isPrime(num):#this function courtesy of #JinnyCho
if num == 1:
return False
if num % 2 == 0 and num > 2:
return False
for i in range(3, int(math.sqrt(num))+1, 2):
if num % i == 0:
return False
return True
def getPrimes(num):
count = 0
i = 1
highPrime = None
while count < num:
if isPrime(i):
count += 1
yield i
i += 1
n = int(raw_input("Enter the value of n: "))
list(getPrimes(n))