I am making a program in python that finds the probability of getting a prime number (E) when n = any number from 0 - 200,000. E = n^2+n+5. However, the "while true, break" cycle doesn't work when t = 200,000. Here is my code:
#import time
#Does E = n^2 + n + 5 always produce prime numbers?
n = 0
t = 0
p = 0
while 3 > 2:
n2 = n*n
E = n2 + n + 5
n = n + 1
if E > 1:
for i in range(2, E):
if((E % i) == 0):
print(E, "is not prime.")
#time.sleep(3)
else:
print("Found a prime number!", E)
#time.sleep(3)
p = p + 1
t = t + 1
if(t >= 200000):
break
fraction = p/t
percent_int = fraction*100
percent = int(percent_int)
print("The probability of getting a prime number is:", percent)
Change this line:
if(t >= 200000):
To:
if(t > 200000):
It just take to long because you run for i in range(2, E): inside while loop.
put print(t) inside while loop to observe progress of program to get idea how long it will take.
Changing your code to this:
n = 0
t = 0
p = 0
while 3 > 2:
n2 = n*n
E = n2 + n + 5
n = n + 1
if E > 1:
for i in range(2, E):
if((E % i) == 0):
pass
else:
print("Found a prime number!", E)
p = p + 1
t = t + 1
print(t)
if(t >= 200000):
break
fraction = p/t
percent_int = fraction*100
percent = int(percent_int)
print("The probability of getting a prime number is:", percent)
and letting it run shows that t is only incremented every time a prime number is found.
You might want to break elsewhere, perhaps set t to 500
Related
I need to test whether n is a multiple of 2 and then divide the number by 2. If the number isn't a multiple of 2, then I have to do 3*n+2.
How do I make it loop so I can get the following: 12, 6, 3, 10, 5, 16, 8, 4, 2, 1?
Here's my current code:
n=12
while n!=0:
if n%2==0:
print (n)
n=n/2
if n!=n%2:
if n !=1:
n = 3*n+2
else:
break
print(n)
First note is that it is 3*n+1, second one is that you have to write n=n/2 in your first if.
Overall this code is what you want:
n = 12
while n != 0:
if n % 2 == 0:
print(n, end=' ')
n = n / 2
elif n % 2 != 0:
if n != 1:
print(n, end=' ')
n = 3 * n + 1
else:
print(1)
break
Or this:
n = 12
while n > 1:
if n % 2 == 0:
print(n, end=' ')
n = n / 2
elif n % 2 != 0:
if n != 1:
print(n, end=' ')
n = 3 * n + 1
else:
print(1)
Good luck
First of all your formula of 3*n + 2 will lead to infinite loop. According your sample output, it needs to be 3*n + 1.
n = 12
while n >= 1:
print(n, end=' ')
if n == 1:
break
if n % 2 == 0:
n = n // 2
else:
n = 3 * n + 1
print("Number of primes must be greater than 2")
number = int(input("Number of primes: "))
if number < 1:
print("Invalid input")
exit()
print(2)
print(3)
i = 0
no_primes = 2
while 1 < 2:
m = 6 * i - 1
n = 6 * i + 1
if (2 ** m) % m == 2:
print(m)
no_primes += 1
if no_primes == number:
break
if (2 ** n) % n == 2:
print(n)
no_primes += 1
if no_primes == number:
break
i += 1
My code uses the fact that primes can be expressed in the form 6n-1 or 6n+1 except for 2 and 3. My while loop looks quite strange but I don't have the expertise to manoeuvre with loops consisting of two variables (no_primes and i in this case). When I generate the first 1000 primes, it skips a few, ending with 7789 instead of 7919. Does anybody know why? Also, sorry if the code looks redundant. If it is, please do state how I can improve it
I started python only a few weeks ago, thought you'll should know
I'm not sure checking (2 ** m) % m == 2 and (2 ** n) % n == 2 will give you all prime numbers.
Have you compared with a more brute force approach?
print("Number of primes must be greater than 2")
number = int(input("Number of primes: "))
if number < 1:
print("Invalid input")
exit()
elif number == 1:
print(2)
else:
print(2)
print(3)
prime_set = {2,3}
i = 1
while len(prime_set) < number:
m = 6 * i - 1
n = 6 * i + 1
if all(m % p != 0 for p in prime_set):
prime_set.add(m)
print(m)
if all(n % p != 0 for p in prime_set):
prime_set.add(n)
print(n)
i+=1
Here the solution edited by #Aqeel for improved Efficiency:
import time
import math
number = int(input("Number of primes: "))
t_0 = time.time()
if number < 1:
print("Invalid input")
exit()
elif number == 1:
print(2)
else:
print(2)
print(3)
primes = [2, 3]
i = 1
while len(primes) < number:
prime_m = True
prime_n = True
m = 6 * i - 1
n = 6 * i + 1
sqrt_m = math.sqrt(m)
sqrt_n = math.sqrt(n)
for prime in primes:
if prime > sqrt_m:
break
if m % prime == 0:
prime_m = False
break
if prime_m:
print(m)
primes.append(m)
if len(primes) == number:
break
for prime in primes:
if prime > sqrt_n:
break
if n % prime == 0:
prime_n = False
break
if prime_n:
print(n)
primes.append(n)
i += 1
t_1 = time.time()
print(f"Found %s prime numbers in %ss" % (number, t_1 - t_0))
The answer to your issue is that you are printing non-prime numbers.
Running your code (with input 1000) provides 1000 numbers, but checking these numbers with a proper is_prime() function yields these numbers that are not primes:
341
1105
1387
1729
2047
2465
2701
2821
3277
4033
4369
4681
5461
6601
As answered by #Tranbi, (2 ** m) % m == 2 is not a proper test for testing primes. Check out this answer for a better solution
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)
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)
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))