def gcd2(m, n):
factor = 1
while m > 1 and n > 1:
if m % 2 == 0 and n % 2 == 0:
factor *= 2
m /= 2
n /= 2
continue
elif m % 2 != 0 and n % 2 != 0:
m, n = abs(m - n) / 2, min(m, n)
continue
if m % 2 == 0:
m /= 2
if n % 2 == 0:
n /= 2
if m == 0 or n == 0:
out = m + n
elif n == m:
out = n
elif m == 1 or n == 1:
out = 1
return factor * out
def gcd(m, n):
if m == 0:
return n
if n == 0:
return m
if m == n:
return n
if m == 1 or n == 1:
return 1
if m % 2 == 0 and n % 2 == 0:
return 2 * gcd(m / 2, n / 2)
if m % 2 == 0 and n % 2 != 0:
return gcd(m / 2, n)
if n % 2 == 0 and m % 2 != 0:
return gcd(m, n / 2)
if m % 2 != 0 and n % 2 != 0:
if n > m:
return gcd((n-m)/2, m)
else:
return gcd((m-n)/2, n)
import random
import timeit
for test in range(100):
a, b = random.randint(0, 100), random.randint(0, 100)
fa = gcd(a, b)
fb = gcd2(a, b)
assert fa == fb, 'Not ok'
# number = 10 ** 5
# print timeit.timeit('gcd(a, b)', setup=s, number=number)
# print timeit.timeit('gcd2(a, b)', setup=s, number=number)
print 'ok'
ZGVmIGdjZDIobSwgbik6CiAgICBmYWN0b3IgPSAxCgogICAgd2hpbGUgbSA+IDEgYW5kIG4gPiAxOgoKICAgICAgICBpZiBtICUgMiA9PSAwIGFuZCBuICUgMiA9PSAwOgogICAgICAgICAgICBmYWN0b3IgKj0gMgogICAgICAgICAgICBtIC89IDIKICAgICAgICAgICAgbiAvPSAyCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgZWxpZiBtICUgMiAhPSAwIGFuZCBuICUgMiAhPSAwOgogICAgICAgICAgICBtLCBuID0gYWJzKG0gLSBuKSAvIDIsIG1pbihtLCBuKQogICAgICAgICAgICBjb250aW51ZQoKICAgICAgICBpZiBtICUgMiA9PSAwOgogICAgICAgICAgICBtIC89IDIKCiAgICAgICAgaWYgbiAlIDIgPT0gMDoKICAgICAgICAgICAgbiAvPSAyCgogICAgaWYgbSA9PSAwIG9yIG4gPT0gMDoKICAgICAgICBvdXQgPSBtICsgbgogICAgZWxpZiBuID09IG06CiAgICAgICAgb3V0ID0gbgogICAgZWxpZiBtID09IDEgb3IgbiA9PSAxOgogICAgICAgIG91dCA9IDEKCiAgICByZXR1cm4gZmFjdG9yICogb3V0CgoKZGVmIGdjZChtLCBuKToKICAgIGlmIG0gPT0gMDoKICAgICAgICByZXR1cm4gbgoKICAgIGlmIG4gPT0gMDoKICAgICAgICByZXR1cm4gbQoKICAgIGlmIG0gPT0gbjoKICAgICAgICByZXR1cm4gbgoKICAgIGlmIG0gPT0gMSBvciBuID09IDE6CiAgICAgICAgcmV0dXJuIDEKCiAgICBpZiBtICUgMiA9PSAwIGFuZCBuICUgMiA9PSAwOgogICAgICAgIHJldHVybiAyICogZ2NkKG0gLyAyLCBuIC8gMikKCiAgICBpZiBtICUgMiA9PSAwIGFuZCBuICUgMiAhPSAwOgogICAgICAgIHJldHVybiBnY2QobSAvIDIsIG4pCgogICAgaWYgbiAlIDIgPT0gMCBhbmQgbSAlIDIgIT0gMDoKICAgICAgICByZXR1cm4gZ2NkKG0sIG4gLyAyKQoKICAgIGlmIG0gJSAyICE9IDAgYW5kIG4gJSAyICE9IDA6CiAgICAgICAgaWYgbiA+IG06CiAgICAgICAgICAgIHJldHVybiBnY2QoKG4tbSkvMiwgbSkKCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIGdjZCgobS1uKS8yLCBuKQoKaW1wb3J0IHJhbmRvbQppbXBvcnQgdGltZWl0Cgpmb3IgdGVzdCBpbiByYW5nZSgxMDApOgogICAgYSwgYiA9IHJhbmRvbS5yYW5kaW50KDAsIDEwMCksIHJhbmRvbS5yYW5kaW50KDAsIDEwMCkKICAgIGZhID0gZ2NkKGEsIGIpCiAgICBmYiA9IGdjZDIoYSwgYikKICAgIGFzc2VydCBmYSA9PSBmYiwgJ05vdCBvaycKCiMgbnVtYmVyID0gMTAgKiogNQojIHByaW50IHRpbWVpdC50aW1laXQoJ2djZChhLCBiKScsIHNldHVwPXMsIG51bWJlcj1udW1iZXIpCiMgcHJpbnQgdGltZWl0LnRpbWVpdCgnZ2NkMihhLCBiKScsIHNldHVwPXMsIG51bWJlcj1udW1iZXIpCnByaW50ICdvaycK