-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathprimitive-problem.py
55 lines (50 loc) · 1.37 KB
/
primitive-problem.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import math
def modexp_lr(a, b, n):
r = 1
for bit in reversed(_bits_of_n(b)):
r = r * r % n
if bit == 1:
r = r * a % n
return r
def _bits_of_n(n):
bits = []
while n:
bits.append(n % 2)
n /= 2
return bits
def p_factors(num, num_c, p_to_test, prime_factors):
while num_c % 2 == 0:
num_c /= 2
if 2 in prime_factors:
prime_factors[2] += 1
else:
prime_factors[2] = 1
for x in xrange(3, int(math.sqrt(num_c))+1,2):
while num_c % x == 0:
if x in prime_factors:
prime_factors[x] += 1
else:
prime_factors[x] = 1
num_c /= x
if num_c > 2:
prime_factors[num_c] = 1
p_to_test = [(num-1)/x for x in prime_factors]
return p_to_test, prime_factors
def main():
num = input()
num_c = num-1
p_to_test = []
prime_factors = {}
p_to_test,prime_factors = p_factors(num, num_c, p_to_test, prime_factors)
num_of_p_roots = 1
for key,value in prime_factors.iteritems():
num_of_p_roots *= (((key ** value)/key) * ((key-1)))
for x in xrange(2, num):
flag = 0
for y in p_to_test:
if modexp_lr(x,y,num) != 1:
flag += 1
if flag == len(p_to_test):
print x, num_of_p_roots
break
main()