Given a prime number n, the task is to find its primitive root under modulo n. The primitive root of a prime number n is an integer r between[1, n-1] such that the values of r^x(mod n) where x is in the range[0, n-2] are different. Return -1 if n is a non-prime number.
Examples:
Input : 7
Output : Smallest primitive root = 3
Explanation: n = 7
3^0(mod 7) = 1
3^1(mod 7) = 3
3^2(mod 7) = 2
3^3(mod 7) = 6
3^4(mod 7) = 4
3^5(mod 7) = 5
Input : 761
Output : Smallest primitive root = 6
A simple solution is to try all numbers from 2 to n-1. For every number r, compute values of r^x(mod n) where x is in the range[0, n-2]. If all these values are different, then return r, else continue for the next value of r. If all values of r are tried, return -1.
An efficient solution is based on the below facts.
If the multiplicative order of a number r modulo n is equal to Euler Totient Function ?(n) ( note that the Euler Totient Function for a prime n is n-1), then it is a primitive root.
1- Euler Totient Function phi = n-1 [Assuming n is prime]
1- Find all prime factors of phi.
2- Calculate all powers to be calculated further
using (phi/prime-factors) one by one.
3- Check for all numbered for all powers from i=2
to n-1 i.e. (i^ powers) modulo n.
4- If it is 1 then 'i' is not a primitive root of n.
5- If it is never 1 then return i;.
Although there can be multiple primitive roots for a prime number, we are only concerned with the smallest one. If you want to find all the roots, then continue the process till p-1 instead of breaking up by finding the first primitive root.
C++
#include<bits/stdc++.h>
using namespace std;
bool isPrime( int n)
{
if (n <= 1) return false ;
if (n <= 3) return true ;
if (n%2 == 0 || n%3 == 0) return false ;
for ( int i=5; i*i<=n; i=i+6)
if (n%i == 0 || n%(i+2) == 0)
return false ;
return true ;
}
int power( int x, unsigned int y, int p)
{
int res = 1;
x = x % p;
while (y > 0)
{
if (y & 1)
res = (res*x) % p;
y = y >> 1;
x = (x*x) % p;
}
return res;
}
void findPrimefactors(unordered_set< int > &s, int n)
{
while (n%2 == 0)
{
s.insert(2);
n = n/2;
}
for ( int i = 3; i <= sqrt (n); i = i+2)
{
while (n%i == 0)
{
s.insert(i);
n = n/i;
}
}
if (n > 2)
s.insert(n);
}
int findPrimitive( int n)
{
unordered_set< int > s;
if (isPrime(n)== false )
return -1;
int phi = n-1;
findPrimefactors(s, phi);
for ( int r=2; r<=phi; r++)
{
bool flag = false ;
for ( auto it = s.begin(); it != s.end(); it++)
{
if (power(r, phi/(*it), n) == 1)
{
flag = true ;
break ;
}
}
if (flag == false )
return r;
}
return -1;
}
int main()
{
int n = 761;
cout << " Smallest primitive root of " << n
<< " is " << findPrimitive(n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static boolean isPrime( int n)
{
if (n <= 1 )
{
return false ;
}
if (n <= 3 )
{
return true ;
}
if (n % 2 == 0 || n % 3 == 0 )
{
return false ;
}
for ( int i = 5 ; i * i <= n; i = i + 6 )
{
if (n % i == 0 || n % (i + 2 ) == 0 )
{
return false ;
}
}
return true ;
}
static int power( int x, int y, int p)
{
int res = 1 ;
x = x % p;
while (y > 0 )
{
if (y % 2 == 1 )
{
res = (res * x) % p;
}
y = y >> 1 ;
x = (x * x) % p;
}
return res;
}
static void findPrimefactors(HashSet<Integer> s, int n)
{
while (n % 2 == 0 )
{
s.add( 2 );
n = n / 2 ;
}
for ( int i = 3 ; i <= Math.sqrt(n); i = i + 2 )
{
while (n % i == 0 )
{
s.add(i);
n = n / i;
}
}
if (n > 2 )
{
s.add(n);
}
}
static int findPrimitive( int n)
{
HashSet<Integer> s = new HashSet<Integer>();
if (isPrime(n) == false )
{
return - 1 ;
}
int phi = n - 1 ;
findPrimefactors(s, phi);
for ( int r = 2 ; r <= phi; r++)
{
boolean flag = false ;
for (Integer a : s)
{
if (power(r, phi / (a), n) == 1 )
{
flag = true ;
break ;
}
}
if (flag == false )
{
return r;
}
}
return - 1 ;
}
public static void main(String[] args)
{
int n = 761 ;
System.out.println( " Smallest primitive root of " + n
+ " is " + findPrimitive(n));
}
}
|
Python3
from math import sqrt
def isPrime( n):
if (n < = 1 ):
return False
if (n < = 3 ):
return True
if (n % 2 = = 0 or n % 3 = = 0 ):
return False
i = 5
while (i * i < = n):
if (n % i = = 0 or n % (i + 2 ) = = 0 ) :
return False
i = i + 6
return True
def power( x, y, p):
res = 1
x = x % p
while (y > 0 ):
if (y & 1 ):
res = (res * x) % p
y = y >> 1
x = (x * x) % p
return res
def findPrimefactors(s, n) :
while (n % 2 = = 0 ) :
s.add( 2 )
n = n / / 2
for i in range ( 3 , int (sqrt(n)), 2 ):
while (n % i = = 0 ) :
s.add(i)
n = n / / i
if (n > 2 ) :
s.add(n)
def findPrimitive( n) :
s = set ()
if (isPrime(n) = = False ):
return - 1
phi = n - 1
findPrimefactors(s, phi)
for r in range ( 2 , phi + 1 ):
flag = False
for it in s:
if (power(r, phi / / it, n) = = 1 ):
flag = True
break
if (flag = = False ):
return r
return - 1
n = 761
print ( "Smallest primitive root of" ,
n, "is" , findPrimitive(n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool isPrime( int n)
{
if (n <= 1)
{
return false ;
}
if (n <= 3)
{
return true ;
}
if (n % 2 == 0 || n % 3 == 0)
{
return false ;
}
for ( int i = 5; i * i <= n; i = i + 6)
{
if (n % i == 0 || n % (i + 2) == 0)
{
return false ;
}
}
return true ;
}
static int power( int x, int y, int p)
{
int res = 1;
x = x % p;
while (y > 0)
{
if (y % 2 == 1)
{
res = (res * x) % p;
}
y = y >> 1;
x = (x * x) % p;
}
return res;
}
static void findPrimefactors(HashSet< int > s, int n)
{
while (n % 2 == 0)
{
s.Add(2);
n = n / 2;
}
for ( int i = 3; i <= Math.Sqrt(n); i = i + 2)
{
while (n % i == 0)
{
s.Add(i);
n = n / i;
}
}
if (n > 2)
{
s.Add(n);
}
}
static int findPrimitive( int n)
{
HashSet< int > s = new HashSet< int >();
if (isPrime(n) == false )
{
return -1;
}
int phi = n - 1;
findPrimefactors(s, phi);
for ( int r = 2; r <= phi; r++)
{
bool flag = false ;
foreach ( int a in s)
{
if (power(r, phi / (a), n) == 1)
{
flag = true ;
break ;
}
}
if (flag == false )
{
return r;
}
}
return -1;
}
public static void Main(String[] args)
{
int n = 761;
Console.WriteLine( " Smallest primitive root of " + n
+ " is " + findPrimitive(n));
}
}
|
Javascript
<script>
function isPrime(n) {
if (n <= 1)
return false ;
if (n <= 3)
return true ;
if (n % 2 == 0 || n % 3 == 0)
return false ;
for (let i = 5; i * i <= n; i = i + 6)
if (n % i == 0 || n % (i + 2) == 0)
return false ;
return true ;
}
function power(x, y, p) {
let res = 1;
x = x % p;
while (y > 0) {
if (y & 1)
res = (res * x) % p;
y = y >> 1;
x = (x * x) % p;
}
return res;
}
function findPrimefactors(s, n) {
while (n % 2 == 0) {
s.add(2);
n = n / 2;
}
for (let i = 3; i <= Math.sqrt(n); i = i + 2) {
while (n % i == 0) {
s.add(i);
n = n / i;
}
}
if (n > 2)
s.add(n);
}
function findPrimitive(n) {
let s = new Set();
if (isPrime(n) == false )
return -1;
let phi = n - 1;
findPrimefactors(s, phi);
for (let r = 2; r <= phi; r++) {
let flag = false ;
for (let it of s) {
if (power(r, phi / it, n) == 1) {
flag = true ;
break ;
}
}
if (flag == false )
return r;
}
return -1;
}
let n = 761;
document.write( " Smallest primitive root of " + n + " is " + findPrimitive(n));
</script>
|
Output:
Smallest primitive root of 761 is 6
Time Complexity : O(n^2 * logn)
Space Complexity : O(sqrt(n))
This article is contributed by Niteesh kumar and Sahil Chhabra (akku). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.