Challenge: Primitive Problem
Subdomeniu: Number Theory (number-theory)
Scor cont: 20.0 / 20
Submission status: Accepted
Submission score: 1.0
Submission ID: 464721731
Limbaj: python3
Link challenge: https://www.hackerrank.com/challenges/primitive-problem/problem
Cerinta
We define a *primitive root* of prime number $p$ to be some integer $g \in [1, p-1]$ satisfying the property that all values of $g^x \bmod p$ where $x \in [0, p - 2]$ are different.
For example: if $p = 7$, we want to look at all values of $g$ in the inclusive range from $1$ to $p - 1 = 6$. For $g = 3$, the powers of $g^x \bmod p$ (where $x$ is in the inclusive range from $0$ to $p - 2 = 5$) are as follows:
- $3^0=1 \pmod 7$
- $3^1=3 \pmod 7$
- $3^2=2 \pmod 7$
- $3^3=6 \pmod 7$
- $3^4=4 \pmod 7$
- $3^5=5 \pmod 7$
Note that each of these evaluates to one of the six distinct integers in the range $[1, p-1]$.
Given prime $p$, find and print the following values as two space-separated integers on a new line:
1. The smallest primitive root of prime $p$.
2. The total number of primitive roots of prime $p$.
**Need Help?** Check out a breakdown of this process at [Math Stack Exchange](http://math.stackexchange.com/questions/124408/finding-a-primitive-root-of-a-prime-number).
Input Format
A single prime integer denoting $p$.
Output Format
Print two space-separated integers on a new line, where the first value is the smallest primitive root of $p$ and the second value is the total number of primitive roots of $p$.
Constraints
+ $2 < p < 10^9$
Cod sursa
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 range(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 = int(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.items():
num_of_p_roots *= (((key ** value) // key) * ((key - 1)))
for x in range(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()
HackerRank Number Theory – Primitive Problem
