Reputation: 55
So I have written a program (see below) to run a series of test cases and for each case determine if X exists for A≡X^2(modM) using Euler's Criterion. It works fine for small test cases, such as when A = 0 and M = 2 or A = 4 and M = 7, but when I consider larger test cases, such as when A = 83715323 and M = 118299443, the program just hangs on line 15 (shown below). Why is this program hanging? Is it a limit of python? Should I perhaps just redo it in something like C++?
The Problem Line
if((A[case]**((M[case] - 1)/2) - 1) % M[case]) == 0:
The Whole Program
number_of_cases = int(raw_input())
A = []
M = []
for case in range(number_of_cases):
A_M = raw_input().split()
A.append(int(A_M[0]))
M.append(int(A_M[1]))
for case in range(number_of_cases):
solution_exists = 0
if((A[case]**((M[case] - 1)/2) - 1) % M[case]) == 0:
print ("YES")
break
else:
print("NO")
Upvotes: 2
Views: 594
Reputation: 176810
The integer calculated by A[case]**((M[case] - 1)/2) - 1)
can get very large very quickly. It will take a lot of time and memory to calculate this number using any language.
Instead, take advantage of Python's pow
operator and its third argument, which allows for efficient modular exponentiation.
Try changing
if((A[case]**((M[case] - 1)/2) - 1) % M[case]) == 0:
to
if pow(A[case], (M[case] - 1)/2 - 1, M[case]) == 0:
The large number A[case]**((M[case] - 1)/2) - 1)
is not calculated here: Python increments the power gradually and keeps track of the remainder modulo M[case]
at each step.
Upvotes: 4
Reputation: 8805
You are performing modular exponentiation.
For that reason, you don't need to calculate A[case]**((M[case] - 1)/2)
in one statement. This is likely what is causing your hang.
Use the fact that
x**(n) % m == {(x**(n-1) % m) * x} % m
i.e. you can calculate the remainder of x^n
for arbitrarily large n without calculating x^n
directly by multiplying then getting the remainder repeatedly.
Try breaking up the exponentiation (see the "Memory-efficient method" section of the wiki article) and seeing if it's still slow.
My bet is that it isn't.
Upvotes: 2