Memory Error in Python Primality Testing program - python-3.x

def repeated(m, result, a, s, d):
check = True
r = 0
while r <= s - 1:
if result == m - 1:
check = False
return check
result = (result ** 2) % m
r = r + 1
return check
I need to write a primality testing python program to test very large numbers, like at least 100-digit numbers. The code above is part of the code for Miller Rabin deterministic primality test for repeated squaring. It works really slow for large numbers. How can I speed it up? It is for a project. Thanks!

your problem is probably the (result ** 2) % m, use the 3 argument version of pow that do the same but more efficiently because the algorithm use is the Modular exponentiation and that is much better than first doing x**n and then calculate its modulo. this way you are guaranty to never have a number bigger than m while if you do (x**n) % m you can have that x**n is very much bigger than m that may be the cause your problems
Also no need for the check variable and you don't use a.
Also as you go from 0 to s-1, better use range
def repeated(m, result, s, d):
for r in range(s):
if result == m - 1:
return False
result = pow(result, 2, m )
return True
Now for this part of the test
if
you need a, d, s, and n this is how I would do it
def mr_check(n,a,s,d):
result = pow(a,d,n)
if result == 1 :
return False
for r in range(s):
result = pow(result,2,n)
if result == n-1:
return False
return True

Related

Converting Iterative Code to Recursive Code Python3

I'm a beginner programming student and I've been studying recursion functions in Python3 lately. I'm working on a code that basically provides minimum steps requires for a number N to be M undergoing processes of adding 1, divide 2, or multiple 10. I did an iterative function that works well, but as a beginner student of recursive functions I want to be able to convert the code to a recursive code and in this code I was not successful.
I've been reading about this process lately, but as I said it was a very hard implementation for my skills. I know if I want to convert an iterative code I need to use the main loop condition as my base case and the body of the loop as the recursive step and that is all I know.
I would really appreciate it if you could help me to find the base case and the recursive steps of this code. I don't want you to write my code, I want you to help me in reaching my goals.
ITERATIVE CODE
def scape(N, M, steps=0):
if N == M:
return 0
currentoptions = [N]
while True:
if M in currentoptions:
break
thisround = currentoptions[:]
currentoptions = []
for i in thisround:
if (i%2) == 0:
currentoptions.append(i // 2)
currentoptions.append(i + 1)
currentoptions.append(i * 10)
steps += 1
return steps
EXAMPLE
print(scape(8,1))
OUTPUT -> 3
Because 8/2 -> 4/2 -> 2/2 = 1
It is difficult to use pure recursion here (without passing around auxiliary data structures). YOu could do sth along the following lines:
def scape(opts, M, steps=0):
if M in opts:
return steps
opts_ = []
for N in opts:
if not N%2:
opts_.append(N // 2)
opts_.extend((N + 1, N * 10))
return scape(opts_, M, steps+1)
>>> scape([8], 1)
3
Or in order to keep the signature (and not pass around redundant arguments), you could use a recursive helper function:
def scape(N, M):
steps = 0
def helper(opts):
nonlocal steps
if M in opts:
return steps
opts_ = []
for N in opts:
if not N%2:
opts_.append(N // 2)
opts_.extend((N + 1, N * 10))
steps += 1
return helper(opts_)
return helper([N])
>>> scape(8, 1)
3

Interest calculator on Python

I know that this has been asked already, but I'm having trouble with how I should implement this so I'm asking here.
My python code so far is:
def calculate():
p = 10000 # dollars
n = 12 # months
r = 8 # interest %
t = float(raw_input("Type the number of year that the money will be compounded for:"))
b = p * r
a = b ** t
print(a)
calculate()
Math formula
Like John Coleman mentioned in the comments you didn't implement the formula at all.
In your code you just multiplied p with r and b to the power of t.
The right formula looks like this: p*(1+(r/n))**(n*t).
I would recommend you to read an article related to python basic operators you can find one on Python Course.
def calculate():
p = 10000
n = 12
r = .08
t = float(input("Type the number of year that the money will be compounded for:"))
formula = p*(1+(r/n))**(n*t)
return formula
print (calculate())
So you need to return a value since you are writing a function. I would say input all your values into the function directly like so:
def calculate(P, r, n , t):
exponent = n*t
parends = 1 + (r/n)
val = parends ** exponent
ans = P * val
return ans
print(calculate(10000, .08, 12, 1))
I would check out other resources to learn how to use functions. Codeacademy is a good one.
Here is the function just not broken into pieces:
def shorter(P, r, n, t):
return P*(1+(r/n))**(n*t)
print(shorter(10000, .08, 12, 1))

Calculating pow(a,nCr) % m efficiently

I think there are some process for calculating pow(a,nCr)%b?
But I want to know how I can efficiently solve this problem in programming?
I can think of a way that's only ~O(n^2*log(m)) and doesn't require the use of big integers. I have a notion of a faster (something like O(k*log(m)*log(n))) approach if you can factor m and you can factor totient(m/gcd(a^k,m)) for some k, but it gets pretty hairy.
In any case for the O(n^2*log(m)) approach, we'll make use of the fact that nCr == (n-1)C(r-1) + (n-1)Cr
Here's a computation of nCr which exploits that:
def nCr(n0,r0):
memoized = {}
def go(n,r):
if r == 0 or r == n:
return 1
if (n,r) not in memoized:
memoized[(n,r)] = go(n-1,r-1) + go(n-1,r)
return memoized[(n,r)]
return go(n0,r0)
The code for your powChooseMod function would be almost identical:
def powChooseMod(a,n0,r0,m):
memoized = {}
def go(n,r):
if r == 0 or r == n:
return a
if (n,r) not in memoized:
memoized[(n,r)] = go(n-1,r-1) * go(n-1,r) % m
return memoized[(n,r)]
return go(n0,r0)

power (a, n) in PYTHON

POwer in Python. How to write code to display a ^ n using funсtion?
why doesn't this code working?
a = int(input())
n = int(input())
def power(a, n):
for i in range (n):
a=1
a *= n
print(power (a, n))
Few errors:
Changing a will lose your power parameter, use result (or something else).
Move setting result = 1 outside your loop to do so once.
Multiply by a not by n.
Use return to return a value from the function
def power(a, n):
result = 1 # 1 + 2
for _ in range (n):
result *= a # 3
return result # 4
Style notes:
Setting/mutating a parameter is considered bad practice (unless explicitly needed), even if it is immutable as is here.
If you're not going to use the loop variable, you can let the reader know by using the conventional _ to indicate it (_ is a legal variable name, but it is conventional to use it when not needing the variable).
Tip: you can simple use a**n
It doesn't work because your function doesn't return the end value. Add return a to the end of the function.
ALSO:
That is not how a to the power of n is is calculated.
A proper solution:
def power(a,n):
pow_a = a
if n is 0:
return 1
for _ in range(n-1): # Substracting 1 from the input variable n
pow_a *= a # because n==2 means a*a already.
return pow_a
and if you want to be really cool, recursion is the way:
def power_recursive(a,n):
if n is 0:
return 1
elif n is 1:
return a
else:
a *= power_recursive(a,n-1)
return a

11+ digit ints not working

I'm using python 3 for a small extra credit assignment to write an RSA cracker. The teacher has given us a fairly large (large enough to require more than 32 bits) int and the public key. My code works for primes < 32 bits. One of the reasons I chose python 3 is because I heard it can handle arbitrarily large integers. In the python terminal I tested this by doing small things such as 2**35 and factorial(70). This stuff worked fine.
Now that I've written the code, I'm running in to problems with overflow errors etc. Why is it that operations on large numbers seem to work in the terminal but won't work in my actual code? The errors state that they cannot be converted to their C types, so my first guess would be that for some reason the stuff in the python interpreter is not being converter to C types while the coded stuff is. Is there anyway to get this working?
As a first attempt, I tried calculating a list of all primes between 1 and n (the large number). This sort of worked until I realized that the list indexers [ ] only accept ints and explode if the number is higher than int. Also, creating an array that is n in length won't work if n > 2**32. (not to mention the memory this would take up)
Because of this, I switched to using a function I found that could give a very accurate guess as to whether or not a number was prime. These methods are pasted below.
As you can see, I am only doing , *, /, and % operations. All of these seem to work in the interpreter but I get "cannot convert to c-type" errors when used with this code.
def power_mod(a,b,n):
if b < 0:
return 0
elif b == 0:
return 1
elif b % 2 == 0:
return power_mod(a*a, b/2, n) % n
else:
return (a * power_mod(a,b-1,n)) % n
Those last 3 lines are where the cannot convert to c-type appears.
The below function estimates with a very high degree of certainty that a number is prime. As mentioned above, I used this to avoid creating massive arrays.
def rabin_miller(n, tries = 7):
if n == 2:
return True
if n % 2 == 0 or n < 2:
return False
p = primes(tries**2)
if n in p:
return True
s = n - 1
r = 0
while s % 2 == 0:
r = r+1
s = s/2
for i in range(tries):
a = p[i]
if power_mod(a,s,n) == 1:
continue
else:
for j in range(0,r):
if power_mod(a, (2**j)*s, n) == n - 1:
break
else:
return False
continue
return True
Perhaps I should be more specific by pasting the error:
line 19, in power_mod
return (a * power_mod(a,b-1,n)) % n
OverflowError: Python int too large to convert to C double
This is the type of error I get when performing arithmetic. Int errors occur when trying to create incredibly large lists, sets etc
Your problem (I think) is that you are converting to floating point by using the / operator. Change it to // and you should stay in the int domain.
Many C routines still have C int limitations. Do your work using Python routines instead.

Resources