Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
Modular Cramer's rule solution in Clear category for Hubspot Amulet by martin_b
def egcd(a, b):
# extended euclidean algorithm
x, y, u, v = 0, 1, 1, 0
while a != 0:
q, r = b // a, b % a
m, n = x - u * q, y - v * q
b, a, x, y, u, v = a, r, u, v, m, n
return b, x, y
def checkio(m):
(_, f2, f3), (s1, _, s3), (t1, t2, _) = m
# modular version of the Cramer's rule
# the determinant
d = 1 - s3 * t2 - f2 * (s1 - s3 * t1) + f3 * (s1 * t2 - t1)
# modular inverse of the determinant to get 1/d
g, id, _ = egcd(d, 360)
# numerator determinants
dx = -225 * (s1 - s3 * t1) + 315 * (s1 * t2 - t1)
dy = 225 * (1 - f3 * t1) - 315 * (t2 - f2 * t1)
dz = -225 * (s3 - f3 * s1) + 315 * (1 - f2 * s1)
# solutions mod 360, in the range -180..180
idm = id % (360 // g)
x = (idm * dx // g + 180) % 360 - 180
y = (idm * dy // g + 180) % 360 - 180
z = (idm * dz // g + 180) % 360 - 180
return [x, y, z]
#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
def check_it(func, matrix):
result = func(matrix)
if not all(-180 <= el <= 180 for el in result):
print("The angles must be in range from -180 to 180 inclusively.")
return False
f, s, t = result
temp = [0, 0, 0]
temp[0] += f
temp[1] += matrix[0][1] * f
temp[2] += matrix[0][2] * f
temp[0] += matrix[1][0] * s
temp[1] += s
temp[2] += matrix[1][2] * s
temp[0] += matrix[2][0] * t
temp[1] += matrix[2][1] * t
temp[2] += t
temp = [n % 360 for n in temp]
if temp == [0, 225, 315]:
return True
else:
print("This is the wrong final position {0}.".format(temp))
return False
assert check_it(checkio,
[[1, 2, 3],
[3, 1, 2],
[2, 3, 1]]), "1st example"
assert check_it(checkio,
[[1, 4, 2],
[2, 1, 2],
[2, 2, 1]]), "2nd example"
assert check_it(checkio,
[[1, 2, 5],
[2, 1, 1],
[2, 5, 1]]), "3rd example"
Feb. 23, 2016
Comments: