How to find (a^(b^c)) % (10^9 + 7) in Python for large inputs?
My code just get terminated after a few test cases.
My code:
numbers = list(map(int, input().split()))
x = numbers[2]
y = numbers[1]
z = numbers[0]
m = pow(10,9) + 7
a = pow(y,x)
r = z % m
for i in range (0,a):
r = r*z
r = r % m
print(r)
You should use Fermat's Little Theorem and Pingala's algorithm for power.
a ^ (p - 1) is 1 so if you take (b ^ c) % (10 ^ 9 + 6) that will become 1 (after taking power of a) and for calculating power modulo a number you can use binary approach that is a^2k % M = ((a^k % M)^2) % M and a ^ (2k + 1) % M = ((a % M) * (a^k % M) ^ 2) % M.
f a b c p = modPow a (modPow b c (p - 1)) p
modPow x n p
| n == 0 = 1
| even n =
let val = x ^ (n `div` 2)
in (val * val) `mod` p
| otherwise = (x * modPow x (n-1) p) `mod` p
Related
Problem
Given N, return M that satisfy the equation: N + M = 2 * (N ^ M)
Constraints
1 <= Test Cases = 10^5;
1 <= N <= 10^18
I came across this problem in one of the hiring challenges.
By trial and error method, I have found a pattern that - Such an M exists between N/3 and 3N and that N + M is an Even number. So I code it up and upon submission, my solution only managed to pass only half of the test cases. This is not much of an optimisation as this method's time complexity is same as that of Brute force solution.
I know that my solution is not the Optimal solution.
Here's my solution:
def solve(n):
m = n//3
end = 3*n
# If both m and n are odd/even, their sum will be even
if (m&1 == 1 and n & 1 == 1) or (m&1 == 0 and n&1 == 0):
inc = 2
else:
m += 1
inc = 2
while m <= end:
if (n + m) == 2 * (n ^ m):
return m
m += inc
Could someone provide me some hints/methods/algorithm to get an Optimal Solution. Thanks!
The bottom bit of m is determined (since n+m must be even). Given that bottom bit, the next bit is determined, and so on.
That observation leads to this O(log n) solution:
def solve(n):
b = 1
m = 0
while n + m != 2 * (n ^ m):
mask = 2 * b - 1
if ((n + m) & mask) != ((2 * (n ^ m)) & mask):
m += b
b *= 2
return m
Another way to implement this is to find the smallest bit in which m+n and 2*(n^m) differ, and toggle that bit in m. That results in this very compact code (using the new walrus operator, and some bit-twiddling tricks):
def solve(n):
m = 0
while r := n + m ^ 2 * (n ^ m):
m |= r & -r
return m
I have set up a large table of constraints, as such:
value_n=1319677575750664593269928592823122088231102756079484792845079638972350094036132691958059688916820689747030184510113829740113041751835106779040361964704732781674939111970921386382076965209456061359009064103696057581141587585573457409644899626416953339600078178839886677162434056466419378007334549881514299423667452655244230384294862385143577667675301828094532154331478209619704980444350466007158636501159025323438259949492591777519923746198537834074290240109117233
value_a=342691274423584349791056473125411134098438481683180895903867322580082465637958239934448846612075098614285219068292647847040005389205050272757677433858953494823759242244829180636673330238802274884481886959589470615694177803698174718690765848886907721839332228324388423577817424201793491303906581758910921445168317877902384290187158732544836897687264045955879735934334920222645677067477720579027115764510363046519727124832263309244176383203195395120143396393280178
value_c=966614148477848624030200621625258849031380625915218872283078816676928740125344244698257425964002821854099461580094436358123535723290845114669846893220163142039503329214545667563764436310988727558365456532947041619144359286499858057080380889267035885314605337688144688305837511055021190348080983083350965687703714494963398464234969815079998913589315977406087449734769882954669673024108621512376903207095402574078110055132403183173806026764738715566878703793779398
value_sigma=8464844919528024050776743166493391951099685330616502566136514764715071037185126965166263456592507665693764888945402100735300264199432720007286127252491425
value_tau=10382212427405516607551590772908169835382410408959523296597160297199683505639053103035865826384731049385602808678770211265514520018139117856623297634063128
value_rho=2180308065203712074036416623837957892343118044869765657224934920507007488415740097667016690791656923501004556879088800046225392947371826678430341848539725784764496743600951899723067587234367926146679537689197024965709655834286819439034454072201704826252187806261154259276367446581026005274199093558591833001447262700832466548485390911986069977032843293472245605677321290489737169381053552716457700040526454320831401386889040870267821074531233371107830697865854527
sigma = Int('sigma')
tau = Int('tau')
rho = Int('rho')
random_1340 = Int('random_1340')
random_1160 = Int('random_1160')
random_335 = Int('random_335')
n = Int('n')
a = Int('a')
c = Int('c')
p = Int('p')
q = Int('q')
a_to_n = Int('a_to_n')
a_to_flag = Int('a_to_flag')
a_to_p_1 = Int('a_to_p_1')
kappa = Int('kappa')
flag = Int('flag')
equations = [
flag < p,
n == value_n, a == value_a, c == value_c, sigma == value_sigma, tau == value_tau, rho == value_rho,
a_to_n == a ** n,
a_to_flag == a ** flag,
a_to_p_1 == a ** (p-1),
c == ((((a_to_n % n) ** kappa) % n) * (a_to_flag % n)) % n,
n == p ** 2 * q,
kappa >= 1, kappa <= n - 1,
p > q, 2 * q > p,
a >= 2, a <= n - 1 , a_to_p1 % (p * p) != 1,
sigma >= 2, sigma <= q - 1,
random_1340 >= 1, random_1340 <= 2**1340, random_1160 >= 1, random_1160 <= 2**1160, random_335 >= 1, random_335 <= 2 ** 335,
tau == (p * p * sigma - random_1340) / q ** 2 + random_335,
rho == p * p * sigma + q * q * tau + random_1160
]
When I try to solve, two of the equations are giving me issues:
[
c == ((((a_to_n % n) ** kappa) % n) * (a_to_flag % n)) % n,
a_to_p1 % (p * p) != 1,
]
I get a z3.z3types.Z3Exception: Z3 integer expression expected:
c == ((((a_to_n % n) ** kappa) % n) * (a_to_flag % n)) % n,
File "/home/retep/.local/lib/python3.8/site-packages/z3/z3.py", line 2411, in __mod__
_z3_assert(a.is_int(), "Z3 integer expression expected")
A is defined as an Int type, so why does this happen and how do I resolve it?
The problem here is that ** produces a Real number, not an Int, and thus you cannot combine the result with % later on. Here's a simple example to illustrate:
>>> from z3 import *
>>> a, n = Ints('a n')
>>> (a ** n).sort()
Real
That is, the expression a ** n is Real valued; so you cannot take the modulus with an integer later on. To convert back to integer, use ToInt:
>>> ToInt(a ** n).sort()
Int
So, whenever you use **, wrap the result in a call to ToInt to avoid this issue.
Having said that, mixing reals and integers this way will no doubt make your problem quite hard to deal with in z3. I wouldn't be surprised if z3 had very hard time solving your equations, assuming they're not merely constant folding. Perhaps you should simply stick to Real values for everything, which has a decidable theory. (Doesn't mean z3 can answer your queries easily; it just means z3 can decide it if you are willing to wait long enough and have enough computing resources.)
The following code prints the pythagorean triplet if it is equal to the input, but the problem is that it takes a long time for large numbers like 90,000 to answer.
What can I do to optimize the following code?
1 ≤ n ≤ 90 000
def pythagoreanTriplet(n):
# Considering triplets in
# sorted order. The value
# of first element in sorted
# triplet can be at-most n/3.
for i in range(1, int(n / 3) + 1):
# The value of second element
# must be less than equal to n/2
for j in range(i + 1,
int(n / 2) + 1):
k = n - i - j
if (i * i + j * j == k * k):
print(i, ", ", j, ", ",
k, sep="")
return
print("Impossible")
# Driver Code
vorodi = int(input())
pythagoreanTriplet(vorodi)
Your source code does a brute force search for a solution so it's slow.
Faster Code
def solve_pythagorean_triplets(n):
" Solves for triplets whose sum equals n "
solutions = []
for a in range(1, n):
denom = 2*(n-a)
num = 2*a**2 + n**2 - 2*n*a
if denom > 0 and num % denom == 0:
c = num // denom
b = n - a - c
if b > a:
solutions.append((a, b, c))
return solutions
OP code
Modified OP code so it returns all solutions rather than printing the first found to compare performance
def pythagoreanTriplet(n):
# Considering triplets in
# sorted order. The value
# of first element in sorted
# triplet can be at-most n/3.
results = []
for i in range(1, int(n / 3) + 1):
# The value of second element
# must be less than equal to n/2
for j in range(i + 1,
int(n / 2) + 1):
k = n - i - j
if (i * i + j * j == k * k):
results.append((i, j, k))
return results
Timing
n pythagoreanTriplet (OP Code) solve_pythagorean_triplets (new)
900 0.084 seconds 0.039 seconds
5000 3.130 seconds 0.012 seconds
90000 Timed out after several minutes 0.430 seconds
Explanation
Function solve_pythagorean_triplets is O(n) algorithm that works as follows.
Searching for:
a^2 + b^2 = c^2 (triplet)
a + b + c = n (sum equals input)
Solve by searching over a (i.e. a fixed for an iteration). With a fixed, we have two equations and two unknowns (b, c):
b + c = n - a
c^2 - b^2 = a^2
Solution is:
denom = 2*(n-a)
num = 2*a**2 + n**2 - 2*n*a
if denom > 0 and num % denom == 0:
c = num // denom
b = n - a - c
if b > a:
(a, b, c) # is a solution
Iterate a range(1, n) to get different solutions
Edit June 2022 by #AbhijitSarkar:
For those who like to see the missing steps:
c^2 - b^2 = a^2
b + c = n - a
=> b = n - a - c
c^2 - (n - a - c)^2 = a^2
=> c^2 - (n - a - c) * (n - a - c) = a^2
=> c^2 - n(n - a - c) + a(n - a - c) + c(n - a - c) = a^2
=> c^2 - n^2 + an + nc + an - a^2 - ac + cn - ac - c^2 = a^2
=> -n^2 + 2an + 2nc - a^2 - 2ac = a^2
=> -n^2 + 2an + 2nc - 2a^2 - 2ac = 0
=> 2c(n - a) = n^2 - 2an + 2a^2
=> c = (n^2 - 2an + 2a^2) / 2(n - a)
DarrylG's answer is correct, and I've added the missing steps to it as well, but there's another solution that's faster than iterating from [1, n). Let me explain it, but I'll leave the code up to the reader.
We use Euclid's formula of generating a tuple.
a = m^2 - n^2, b = 2mn, c = m^2 + n^2, where m > n > 0 ---(i)
a + b + c = P ---(ii)
Combining equations (i) and (ii), we have:
2m^2 + 2mn = P ---(iii)
Since m > n > 0, 1 <= n <= m - 1.
Putting n=1 in equation (iii), we have:
2m^2 + 2m - P = 0, ax^2 + bx + c = 0, a=2, b=2, c=-P
m = (-b +- sqrt(b^2 - 4ac)) / 2a
=> (-2 +- sqrt(4 + 8P)) / 4
=> (-1 +- sqrt(1 + 2P)) / 2
Since m > 0, sqrt(b^2 - 4ac) > -b, the only solution is
(-1 + sqrt(1 + 2P)) / 2 ---(iv)
Putting n=m-1 in equation (iii), we have:
2m^2 + 2m(m - 1) - P = 0
=> 4m^2 - 2m - P = 0, ax^2 + bx + c = 0, a=4, b=-2, c=-P
m = (-b +- sqrt(b^2 - 4ac)) / 2a
=> (2 +- sqrt(4 + 16P)) / 8
=> (1 +- sqrt(1 + 4P)) / 4
Since m > 0, the only solution is
(1 + sqrt(1 + 4P)) / 4 ---(v)
From equation (iii), m^2 + mn = P/2; since P/2 is constant,
when n is the smallest, m must be the largest, and vice versa.
Thus:
(1 + sqrt(1 + 4P)) / 4 <= m <= (-1 + sqrt(1 + 2P)) / 2 ---(vi)
Solving equation (iii) for n, we have:
n = (P - 2m^2) / 2m ---(vii)
We iterate for m within the bounds given by the inequality (vi)
and check when the corresponding n given by equation (vii) is
an integer.
Despite generating all primitive triples, Euclid's formula does not
produce all triples - for example, (9, 12, 15) cannot be generated using
integer m and n. This can be remedied by inserting an additional
parameter k to the formula. The following will generate all Pythagorean
triples uniquely.
a = k(m^2 - n^2), b = 2kmn, c = k(m^2 + n^2), for k >= 1.
Thus, we iterate for integer values of P/k until P < 12,
lowest possible perimeter corresponding to the triple (3, 4, 5).
Yo
I don't know if you still need the answer or not but hopefully, this can help.
n = int(input())
ans = [(a, b, c) for a in range(1, n) for b in range(a, n) for c in range(b, n) if (a**2 + b**2 == c**2 and a + b + c == n)]
if ans:
print(ans[0][0], ans[0][1], ans[0][2])
else:
print("Impossible")
I have a working script (Powered by Python 2.7) :
import sys
a=0
b=7
p=0xB12D
x2=0x38F
if (len(sys.argv)>1):
x1=int(sys.argv[1])
if (len(sys.argv)>2):
x2=int(sys.argv[2])
if (len(sys.argv)>3):
p=int(sys.argv[3])
if (len(sys.argv)>4):
a=int(sys.argv[4])
if (len(sys.argv)>5):
b=int(sys.argv[5])
def modular_sqrt(a, p):
""" Find a quadratic residue (mod p) of 'a'. p
must be an odd prime.
Solve the congruence of the form:
x^2 = a (mod p)
And returns x. Note that p - x is also a root.
0 is returned is no square root exists for
these a and p.
The Tonelli-Shanks algorithm is used (except
for some simple cases in which the solution
is known from an identity). This algorithm
runs in polynomial time (unless the
generalized Riemann hypothesis is false).
"""
# Simple cases
#
if legendre_symbol(a, p) != 1:
return 0
elif a == 0:
return 0
elif p == 2:
return p
elif p % 4 == 3:
return pow(a, (p + 1) / 4, p)
# Partition p-1 to s * 2^e for an odd s (i.e.
# reduce all the powers of 2 from p-1)
#
s = p - 1
e = 0
while s % 2 == 0:
s /= 2
e += 1
# Find some 'n' with a legendre symbol n|p = -1.
# Shouldn't take long.
#
n = 2
while legendre_symbol(n, p) != -1:
n += 1
x = pow(a, (s + 1) / 2, p)
b = pow(a, s, p)
g = pow(n, s, p)
r = e
while True:
t = b
m = 0
for m in xrange(r):
if t == 1:
break
t = pow(t, 2, p)
if m == 0:
return x
gs = pow(g, 2 ** (r - m - 1), p)
g = (gs * gs) % p
x = (x * gs) % p
b = (b * g) % p
r = m
def legendre_symbol(a, p):
""" Compute the Legendre symbol a|p using
Euler's criterion. p is a prime, a is
relatively prime to p (if p divides
a, then a|p = 0)
Returns 1 if a has a square root modulo
p, -1 otherwise.
"""
ls = pow(a, (p - 1) / 2, p)
return -1 if ls == p - 1 else ls
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
print ("x")
else:
return x % m
def hexint(i): return int(i,0)
print "a=",a
print "b=",b
print "p=",p
print "x-point=",x2
# Read numbers from file and put them in an array
with open("List.txt","r") as f:
# arrX1 = list(map(int,f.readlines()))
arrX1 = list(map(hexint,f.readlines()))
f.close()
# Open the result file to write to
f = open('Result.txt', 'w')
# Now get x1 for each item in the list of numbers from the file
# then do the calculations
# and write the result
for x1 in arrX1:
z=(x1**3 + a*x1 +b) % p
y1=modular_sqrt(z, p)
z=(x2**3 + a*x2 +b) % p
y2=modular_sqrt(z, p)
print "\nP1\t(%d,%d)" % (x1,y1)
print "P2\t(%d,%d)" % (x2,y2)
s=((-y2)-y1)* modinv(x2-x1,p)
x3=(s**2-x2-x1) % p
y3=((s*(x2-x3)+y2)) % p
result = "\nQ(%d\n,%d)" % (x3,y3)
f.write(result)
f.close()
But errors occur in this script due to a negative value during processing.
(That is, when performing calculations using the "s =" formula, the value becomes negative and the script stops.)
Here is the error:
Traceback (most recent call last):
File "E: \ 005.py", line 148, in <module>
s = ((- y2) -y1) * modinv (x2-x1, p)
TypeError: unsupported operand type (s) for *: 'long' and 'NoneType'
>>>
I need my script not to stop, but to write only the correct result to the file: "Result.txt".
And what was not correctly ignored and continued to work!
Is it possible to ignore this stop?
That is, if an error occurs, do not stop the process and execute other sequential commands?
I am not very strong in the Python language and cannot fix the script so that the function skips this error.
If you expect that function can return wrong value - None - then you should get it separtelly and use if/else to skip it
value = modinv(x2-x1, p)
if value is not None:
s = (-y2-y1) * value
x3 = (s**2-x2-x1) % p
y3 = (s*(x2-x3)+y2) % p
result = "\nQ(%d\n,%d)" % (x3, y3)
f.write(result)
else:
print('TypeError for:', x2, x1, p)
#f.write("\nNo Result")
Eventually you can use try/except to catch this error
try:
s = (-y2-y1) * modinv(x2-x1, p)
x3 = (s**2-x2-x1) % p
y3 = (s*(x2-x3)+y2) % p
result = "\nQ(%d\n,%d)" % (x3, y3)
f.write(result)
except TypeError:
print('TypeError for:', x2, x1, p)
#f.write("\nNo Result")
I am trying to implement the function fast modular exponentiation(b, k, m) which computes:
b(2k) mod m using only around 2k modular multiplications.
I tried this method:
def FastModularExponentiation(b, k, m):
res = 1
b = b % m
while (k > 0):
if ((k & 1) == 1):
res = (res * b) % m
k = k >> 1
b = (b * b) % m
return res
but I am still stuck in same problem which is if I try b = 2, k = 1, m = 10, my code returns 22. However, the correct answer is:
2^(2^1) mod 10 = 2^2 mod 10 = 4
and I cannot find the reason why.
Update: I finally understood that you do not want regular modular exponentiation (i.e., b^k mod m), but b^(2^k) mod m (as you plainly stated).
Using the regular built-in Python function pow this would be:
def FastModularExponentiation(b, k, m):
return pow(b, pow(2, k), m)
Or, without using pow:
def FastModularExponentiation(b, k, m):
b %= m
for _ in range(k):
b = b ** 2 % m
return b
If you know r = phi(m) (Euler's totient function), you could reduce the exponent first: exp = pow(2, k, r) and then calculate pow(b, exp, m). Depending on the input values, this might speed things up.
(This was the original answer when I thought you wanted, b^k mod m)
This is what works for me:
def fast_mod_exp(b, exp, m):
res = 1
while exp > 1:
if exp & 1:
res = (res * b) % m
b = b ** 2 % m
exp >>= 1
return (b * res) % m
The only significant differences I spot is in the last line: return (b * res) % m and that my while loop terminates earlier: while exp > 1 (which should be the same thing you do - except it saves an unnecessary squaring operation).
Also note that the built-in function pow will do all that for free (if you supply a third argument):
pow(4, 13, 497)
# 445
def fast_exponentiation(k, x, q):
# make sure all variables are non-negative
assert (k >= 0 and x >= 0 and q >=1)
result = 1 # define a counter
while x:
if x % 2 == 1:
result = (result * k) % q
k = (k ^ 2) % q
x >> = 1 # bit shift operator, dividing x by 2 ** y thus x >> 2 ** 1 = x / 2
return result