finding first prime number with digit length N - python

I have to make a program that from random numbers with N digits, which N is given by user, the program must print the first prime number it finds.
However, I have to check if a number is prime using the following and only equation: a^p=a mod p. (a is a random number and takes different values each time).
If p passes the test 10 times, then it's a prime, if it fails even once, it's not.
My problem is that "a^p = a mod p" isn't always working. My pals said that it's right and it should work.
Here's my code:
from __future__ import division
import random
found = False
flag = True
def prime(p):
i=0
flag = True
while (i<10) and (flag == True):
i+=1
a=random.randint(1,10)
if a**p!=a%p:
flag=False
break
if flag==True:
return 1
else:
return 0
n = int(raw_input("Enter length: "))
if n==0:
print "Enter another value except: 0"
while found==False:
if n!=0:
x=(10**(n-1))
y=(10**n - 1)
num = random.randrange(x, y)
if prime(num):
print str(num) + " is a prime number"
found=True
else:
print str(num) + " is not a prime number"

The problem is because of the difference between mathematical notation and the Python equivalent.
You have to use Fermat's little theorem to do a probabilistic primality test. The relevant formula is a^p = a (mod p). Note that the (mod p) applies to the whole equation and not only to the right side.
Example: 11 = 6 (mod 5) in math (because 11/5 = 2 with remainder 1, just as 6/5 = 1 with remainder 1), but 11 != 6%5 because 11 != 1.
You have to do %p on both sides of the equation or better yet, use Python's 3 parameter pow function that does exactly what you need (copied from tobias_k's comment).

Related

Why do I get a different answer using math.fmod vs mod operator (positive integers only)

Trying to find the smallest positive integer n such that n! divided by the sum of the digits of n! has a remainder.
Two people approached the problem in similar ways but got different answers. I've read that % and fmod behave differently with negative numbers but there are no negative numbers involved here. Large number calculators online seem to show that the solution arrived at through % is correct.
Using mod operator:
import math
n=1
def func():
global n
intn=[]
#for loop creates a list of integers of the digits of n!
for digit in str(math.factorial(n)):
intn.append(int(digit))
denominator=sum(intn)
#if n!/denominator has a remainder, print n; the program is over. Otherwise, increase n and try again.
if (math.factorial(n))%denominator:
print(n)
else:
n+=1
func()
func()
Changing if (math.factorial(n))%(denominator): to if int((math.factorial(n)))%int(denominator): changed the result so that it is the same as when using .fmod, but again, I don't think that is the correct answer.
Using math.fmod:
import math
# curNum is the variable I'm using to track the integer whose value I'm testing
curNum = 1
# conditionMet is a boolean that will be used to break the while loop of the test
conditionMet = False
while conditionMet == False:
sumDigits = 0
curFactorial = math.factorial(curNum)
curFactorialAsString = str(curFactorial)
#sumDigits = sum(int(curNumAsString))
for curDigit in curFactorialAsString:
sumDigits = sumDigits + int(curDigit)
if math.fmod(curFactorial,sumDigits) != 0:
print("curNum: " + str(curNum) + "curFactorial: " + str(curFactorial) + "sumDigits: " + str(sumDigits))
conditionMet = true
else:
curNum = curNum + 1

Recursive function to know if a number is divisible by 3

I need to create a recursive function which return me true if the input number it's divisible by 3. I know that it's more simple without recursion, but I need to create a function of this type.
I've created a function, but i want to know if it's possible to create a better one, 'cause whit a big 'num', the function doesn't work. I think that I should use this fact: a natural number is divisible by 3 if the sum of its digits is divisible by 3.
This is my code:
def divThree(num):
if num==3:
return true
else:
divThree(num-3)
EDIT: I created a better function, but i don't understand why doesn't return me true if the number is divisible by three. Instead, if it isn't, goes on maximum recursion error.
def recursiveThree(num):
if num==3 or num==6 or num==9:
return true
else:
sum=0
sNum=str(num)
for i in range(0,len(sNum)):
sum=sum+int(sNum[i])
recursiveThree(sum)
The most straightforward solution is to use modulo 3 to check for
divisibility, but that's not going to be recursive.
An alternate solution is to recursively keep dividing by 3 until you get down to 1, but that will stack overflow for large values.
A third solution, which lends itself to recursion, is to leverage the property that if the sum of the digits of a number is divisible by 3, then the number is divisible by 3.
Here's an implementation of the third option that avoids modulo arithmetic and copes with very large numbers:
def divThree(num):
if num < 10:
return (num in [3, 6, 9])
else:
return divThree(sum([int(digit) for digit in str(num)]))
You can add 0 to the list in the first return if you want to consider it divisible by 3 as well.
If you want to accommodate both positive and negative values, prepend:
if num < 0:
return divThree(-num)
as the first check to be performed.
You need to check if the number has zero remainder when using 3 as the divisor.
Use the % operator to check for a remainder. So if you want to see if something is evenly divisible by 3 then use num % 3 == 0 If the remainder is zero then the number is divisible by 3.
This returns true:
print (6 % 3 == 0)
returns True
This returns False:
print (5 % 3 == 0)
returns False
Here is a simple function to check True of False:
def divThree(numb):
return numb % 3 == 0
print (divThree(99))
Edit:
I am not sure how big a number you are trying to check but I tested this function with what I think is a big number and it worked. I could be just not understanding what it is you need thought.
def divThree(numb):
return numb % 3 == 0
print (divThree(4325609549876542987503216540321540104986213754901245217346214390735402153407213540213457183254098263487053214132754073254921534987053245321454))
Returned True
You enlarge recursively the factor to subtract:
def divisible_by_tree(num, factor=3):
if factor < num:
num = divi(num, factor * 2)
if num >= factor:
num -= factor
if factor > 3:
return num
return num == 0
This is kind of an obscure method, and there are several better answers, but implementing a theorem of congruences, you could say:
from random import randint # For test trials
def isDivisByThree(n):
sN = str(n)
if(len(sN) == 1):
bIsProductOfThree=True if(n==3 or n==6 or n==9) else False
return bIsProductOfThree
else:
sumOfDigits = 0
for x in sN:
sumOfDigits += int(x)
# end for
return isDivisByThree(sumOfDigits)
# end if
# end isDivisByThree(...)
def main():
for testTrialCount in range(1, 35+1):
testSubject = randint(1, 2147483647)
result = isDivisByThree(testSubject)
if(result):
print("Test Trial #" + str(testTrialCount) + ": " + str(testSubject) + " is divisble by 3!")
else:
print("Test Trial #" + str(testTrialCount) + ": " + str(testSubject) + " is NOT divisble by 3.")
# end if
# end for
# end main()
main()
This works because of a theorem related to the application of congruences which states: if d|(b-1) then n = (a_k * ... * a_1 * a_0) is divisible by d if and only if the sum of digits a_k + ... + a_1 + a_0 is divisible by d. (Where d is the divisor (3 for this example) and b is the base in which the number is expressed (10 for this example).)
Example output for the first 10 trials:
Test Trial #1: 458327921 is NOT divisble by 3.
Test Trial #2: 23787660 is divisble by 3!
Test Trial #3: 820562190 is divisble by 3!
Test Trial #4: 1466915534 is NOT divisble by 3.
Test Trial #5: 1395854683 is NOT divisble by 3.
Test Trial #6: 1844052852 is divisble by 3!
Test Trial #7: 261731131 is NOT divisble by 3.
Test Trial #8: 624183104 is NOT divisble by 3.
Test Trial #9: 788686237 is NOT divisble by 3.
Test Trial #10: 1075010016 is divisble by 3!
...
Edit:
Ah, I see pjs beat me to this with a similar solution.
You could find out what it would take for the number to become divisible by 3 using the modulo and then subtracting that to num
def divThree(num):
if num % 3 == 0:
return True
a = num % 3
return divThree(num-a)
In C (easy to translate)
bool divisible_by_three (int x) {
if (x < 0) return divisible_by_three (-x);
else if (x >= 3) return divisible_by_three (x % 3);
else return (x == 0);
}
Yes, it's recursive. Exercise for your instructor: Find the bug.

Finding primes in python

I know that python is "slow as dirt", but i would like to make a fast and efficient program that finds primes. This is what i have:
num = 5 #Start at five, 2 and 3 are printed manually and 4 is a multiple of 2
print("2")
print("3")
def isPrime(n):
#It uses the fact that a prime (except 2 and 3) is of form 6k - 1 or 6k + 1 and looks only at divisors of this form.
i = 5
w = 2
while (i * i <= n): #You only need to check up too the square root of n
if (n % i == 0): #If n is divisable by i, it is not a prime
return False
i += w
w = 6 - w
return True #If it isn´t ruled out by now, it is a prime
while True:
if ((num % 2 != 0) and (num % 3 != 0)): #save time, only run the function of numbers that are not multiples of 2 or 3
if (isPrime(num) == True):
print(num) #print the now proved prime out to the screen
num += 2 #You only need to check odd numbers
Now comes my questions:
-Does this print out ALL prime numbers?
-Does this print out any numbers that aren't primes?
-Are there more efficient ways(there probably are)?
-How far will this go(limitations of python), and are there any ways to increase upper limit?
Using python 2.7.12
Does this print out ALL prime numbers?
There are infinitely many primes, as demonstrated by Euclid around 300 BC. So the answer to that question is most likely no.
Does this print out any numbers that aren't primes?
By the looks of it, it doesn't. However, to be sure; why not write a unit test?
Are there more efficient ways(there probably are)? -How far will this go(limitations of python), and are there any ways to increase upper limit?
See Fastest way to list all primes below N or Finding the 10001st prime - how to optimize?
Checking for num % 2 != 0 even though you increment by 2 each time seems pointless.
I have found that this algorithm is faster:
primes=[]
n=3
print("2")
while True:
is_prime=True
for prime in primes:
if n % prime ==0:
is_prime=False
break
if prime*prime>n:
break
if is_prime:
primes.append(n)
print (n)
n+=2
This is very simple. The function below returns True if num is a prime, otherwise False. Here, if we find a factor, other than 1 and itself, then we early stop the iterations because the number is not a prime.
def is_this_a_prime(num):
if num < 2 : return False # primes must be greater than 1
for i in range(2,num): # for all integers between 2 and num
if(num % i == 0): # search if num has a factor other than 1 and itself
return False # if it does break, no need to search further, return False
return True # if it doesn't we reached that point, so num is a prime, return True
I tried to optimize the code a bit, and this is what I've done.Instead of running the loop for n or n/2 times, I've done it using a conditional statements.(I think it's a bit faster)
def prime(num1, num2):
import math
def_ = [2,3,5,7,11]
result = []
for i in range(num1, num2):
if i%2!=0 and i%3!=0 and i%5!=0 and i%7!=0 and i%11!=0:
x = str(math.sqrt(i)).split('.')
if int(x[1][0]) > 0:
result.append(i)
else:
continue
return def_+result if num1 < 12 else result

Using Loop to find Brute Force Prime Numbers using Mersenne Number (Python) (Why isn't my code working?)

I'm trying to write this program that uses looping where it finds Brute Force Prime Numbers using Mersenne. The direction is as follows.
A prime number is a number that is not evenly divisible by any other number (except, trivially, 1). All known methods of determining whether a number is a prime number rely on brute force, that is, exhaustive testing of the possibilities. Write a routine that checks whether a number is prime. Check if it’s even, and if not, check all the odd numbers up to the square root of the number (do you see why the square root is enough?). If the number is not prime, tell the user one factor.
For you demo, you’ll use Mersenne 67, which is 2 to the 67th power minus 1 (see problem 1-4-A): 147573952589676412927 [147,573,952,589,676,412,927]. In 1644, Marin Mersenne conjectured this number was prime. It was not until 1903 that F.N. Cole resolved this conjecture, for which he received a standing ovation at a meeting of the American Mathematical Society. What was the resolution? (i.e., is Mersenne 67 prime?) Use your program to answer this question; your program will probably run for about 2½ minutes, quite an advance over the 2½ centuries it originally took to resolve the issue.
This what what I have so far, but it doesn't seem to run where I can verify my answer. Any inputs would greatly appreciated. Thank you in advance.
def me():
N = int(input("What is the Value of N?="))
Mersenne=(2**N)-1
print(format(Mersenne,',d'))
me()
def is_prime(n):
if is_even(n):
else:
for f in <something that generates odd numbers>:
if is_factor(f,n):
def get_n():
n = raw_input("What is the value of n? ")
return ((2 ** 67)-1) if n == 'm' else int(n)
n = get_n()
p = is_prime(n)
if p:
print("%d is not prime (e.g. factor=%d)" % (n, p))
else:
print("%d is prime")
Try this. It passes pylint and pep8, and it runs on python 2.[4567] and python 3.[01234].
#!/usr/local/cpython-3.4/bin/python
'''Test if a number is prime'''
# pylint: disable=superfluous-parens
# superfluous-parens: Parentheses are good for clarity and portability
import math
def is_factor(numerator, denominator):
'''Return true if numerator is evenly divisible by denominator'''
if numerator % denominator == 0:
return True
else:
return False
def is_even(number):
'''Return true if numerator is evenly divisible by 2'''
return is_factor(number, 2)
def odds_to(maximum):
'''Return odd numbers up to maximum'''
number = 3
while number <= maximum:
yield number
number += 2
def get_factor(number):
'''
Return the lowest factor of number.
If number is prime, return 0
'''
if is_even(number):
return 2
else:
top = int(math.sqrt(number))
for odd_number in odds_to(top):
if is_factor(number, odd_number):
return odd_number
return 0
def get_number():
'''Return the value of Mersenne 67'''
# number = 11
# number = 6
# number = 15
number = 2 ** 67 - 1
return number
def main():
'''Main function'''
number = get_number()
factor = get_factor(number)
if factor == 0:
print("%d is prime" % number)
else:
print("%d is not prime (e.g. factor=%d)" % (number, factor))
main()

Finding the largest prime number "within" a number

For this question, I need to find the largest prime number within a larger number. For the purpose of the example, let's say the larger number is "123456789", then some of the numbers I would have to check are 12, 456, 234567, etc.
I wrote some Python code to figure this out, but it is running very slow for the number I am trying to check. The actual number I am working with is about 10000 digits, so there are a lot of numbers I need to look at. Here is my code:
num = "123456789"
def isPrime(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, long(n**0.5)+1, 2):
if n % x == 0:
return False
return True
def largestPrime():
largest = 2
for i in range(0,len(num)):
for j in range(i+1,len(num)):
if isPrime(long(num[i:j])):
if long(num[i:j]) > largest:
largest =long(num[i:j])
print largest
def main():
largestPrime()
main()
I'm pretty sure this code gives the correct answer, but as I said, it's really slow. Can anyone help me figure out how to speed this up?
Thanks for any help!
I'd probably use the strategy of starting with the total number of digits and seeing if that's prime. Then keep decreasing the digits by one while shifting over to the left to see if that's prime. Let me explain with an example:
123456789
First check the 9-digit number: 123456789
Then check the 8-digit numbers: 23456789, 12345678
Then Check the 7-digit numbers: 3456789, 2345678, 1234567
etc.
One problem I see is that for some large numbers you are going to be testing the same number many times. For example for '123456712345671234567', your code will test '1234567' 3 times. I suggest you make a set that contains no duplicates, then run your prime test on each number. I also think that sorting the numbers is a good idea because we can stop after the first prime is found.
Next if you are dealing with large numbers (e.g. 10000 digits), I suggest using a statistical primality test. Below I made a Miller-Rabin primality test using pseudocode from wikipedia.
I have pretty much rewritten your code :P
import random
num = '3456647867843652345683947582397589235623896514759283590867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876867843652345683947582397589235623896514759283590784235876784235876324650'
def probablyPrime(num, k):
"""Using Miller-Rabin primality test"""
if num == 2 or num == 3:
return True
if num < 2:
return False
if not num & 1:
return False
# find s and d such that n−1 = (2**s)*d with d odd
d = (num-1) >> 1
s = 1
while not (d & 1):
d = d >> 1
s += 1
# run k times
for _ in range(k):
a = random.randint(2, num-2)
x = pow(a, d, num) # more efficient than x = a**d % num
if not (x == 1 or x == num-1):
for _ in range(s-1):
x = (x**2) % num
if x == 1:
return False
if x == num-1:
break
if not x == num-1:
return False
return True
def largestPrime(num):
num_list = set([])
for i in range(0,len(num)+1):
for j in range(i+1,len(num)+1):
inum = int(num[i:j])
# Don't append numbers that have already appeared
if inum not in num_list:
num_list.add(inum)
# Convert to list and sort
num_list = list(num_list)
num_list.sort(reverse=True)
for num in num_list:
print('Checking ' + str(num))
if probablyPrime(num,100):
print('\n' + str(num) + ' is probably the largest prime!')
return
largestPrime(num)
Another way to improve speed might be python's multiprocessing package.
Code:
def isprime(n):
if n == 2:
return str(n)+" is the biggest prime"
if n % 2 == 0:
return isprime(n-1) #not prime, check again for next biggest number
max = n**0.5+1
i = 3
while i <= max:
if n % i == 0:
return isprime(n-1) #not prime, check again for next biggest number
i+=2
return str(n)+" is the biggest prime"
print "Testing 7:",isprime(7)
print "Testing 23:",isprime(23)
print "Testing 2245:",isprime(2245)
print "Testing 222457:",isprime(222457)
print "Testing 727245628:",isprime(727245628)
Output:
>>>
Testing 7: 7 is the biggest prime
Testing 23: 23 is the biggest prime
Testing 2245: 2243 is the biggest prime
Testing 222457: 222437 is the biggest prime
Testing 727245628: 727245613 is the biggest prime

Categories

Resources