Open in App
Not now

# Lucas Primality Test

• Difficulty Level : Hard
• Last Updated : 29 Jul, 2022

A number p greater than one is prime if and only if the only divisors of p are 1 and p. First few prime numbers are 2, 3, 5, 7, 11, 13, …
The Lucas test is a primality test for a natural number n, it can test primality of any kind of number.
It follows from Fermatâ€™s Little Theorem: If p is prime and a is an integer, then a^p is congruent to a (mod p )

Lucasâ€™ Test : A positive number n
is prime if there exists an integer a (1 < a < n) such that :

And for every prime factor q of (n-1),

Examples

Input :  n = 7
Output : 7 is Prime
Explanation : let's take a = 3,
then 3^6 % 7 = 729 % 7 = 1 (1st
condition satisfied). Prime factors
of 6 are 2 and 3,
3^(6/2) % 7 = 3^3 % 7 = 27 % 7 = 6
3^(6/3) % 7 = 3^2 % 7 = 9 % 7 = 2
Hence, 7 is Prime

Input :  n = 9
Output : 9 is composite
Explanation : Let's take a = 2,
then 2^8 % 9 = 256 % 9 = 4
Hence 9 is composite 
lucasTest(n):
If n is even
return composite
Else
Find all prime factors of n-1
for i=2 to n-1
pick 'a' randomly in range [2, n-1]
if a^(n-1) % n not equal 1:
return composite
else
// for all q, prime factors of (n-1)
if a^(n-1)/q % n not equal 1
return prime
Return probably prime

Problems Associated with Lucas’s test are

• Knowing all of the prime factors of n-1
• Finding an appropriate choice for a

## C++

 // C++ Program for Lucas Primality Test  #include  using namespace std;    // function to generate prime factors of n  void primeFactors(int n, vector<int>& factors)  {      // if 2 is a factor      if (n % 2 == 0)          factors.push_back(2);      while (n % 2 == 0)          n = n / 2;                // if prime > 2 is factor      for (int i = 3; i <= sqrt(n); i += 2) {          if (n % i == 0)              factors.push_back(i);          while (n % i == 0)              n = n / i;      }      if (n > 2)      factors.push_back(n);  }    // this function produces power modulo  // some number. It can be optimized to  // using  int power(int n, int r, int q)  {      int total = n;      for (int i = 1; i < r; i++)          total = (total * n) % q;      return total;  }    string lucasTest(int n)  {      // Base cases      if (n == 1)          return "neither prime nor composite";      if (n == 2)          return "prime";      if (n % 2 == 0)          return "composite1";                          // Generating and storing factors      // of n-1      vector<int> factors;      primeFactors(n - 1, factors);        // Array for random generator. This array      // is to ensure one number is generated      // only once      int random[n - 3];      for (int i = 0; i < n - 2; i++)          random[i] = i + 2;                // shuffle random array to produce randomness      shuffle(random, random + n - 3,              default_random_engine(time(0)));        // Now one by one perform Lucas Primality      // Test on random numbers generated.      for (int i = 0; i < n - 2; i++) {          int a = random[i];          if (power(a, n - 1, n) != 1)              return "composite";            // this is to check if every factor          // of n-1 satisfy the condition          bool flag = true;          for (int k = 0; k < factors.size(); k++) {              // if a^((n-1)/q) equal 1              if (power(a, (n - 1) / factors[k], n) == 1) {                  flag = false;                  break;              }          }            // if all condition satisfy          if (flag)              return "prime";      }      return "probably composite";  }    // Driver code  int main()  {      cout << 7 << " is " << lucasTest(7) << endl;      cout << 9 << " is " << lucasTest(9) << endl;      cout << 37 << " is " << lucasTest(37) << endl;      return 0;  }

## Java

 // Java Program for Lucas Primality Test import java.util.*;   class GFG {     static ArrayList factors         = new ArrayList();         // function to generate prime factors of n     static ArrayList primeFactors(int n)     {         // if 2 is a factor         if (n % 2 == 0)             factors.add(2);         while (n % 2 == 0)             n = n / 2;           // if prime > 2 is factor         for (int i = 3; i <= Math.sqrt(n); i += 2) {             if (n % i == 0)                 factors.add(i);             while (n % i == 0)                 n = n / i;         }         if (n > 2)             factors.add(n);         return factors;     }       // this function produces power modulo     // some number. It can be optimized to     // using     static int power(int n, int r, int q)     {         int total = n;         for (int i = 1; i < r; i++)             total = (total * n) % q;         return total;     }       static String lucasTest(int n)     {         // Base cases         if (n == 1)             return "neither prime nor composite";         if (n == 2)             return "prime";         if (n % 2 == 0)             return "composite1";           // Generating and storing factors         // of n-1         primeFactors(n - 1);           // Array for random generator. This array         // is to ensure one number is generated         // only once         int[] random = new int[n - 2];         for (int i = 0; i < n - 2; i++)             random[i] = i + 2;           // shuffle random array to produce randomness         Collections.shuffle(Arrays.asList(random));           // Now one by one perform Lucas Primality         // Test on random numbers generated.         for (int i = 0; i < n - 2; i++) {             int a = random[i];             if (power(a, n - 1, n) != 1)                 return "composite";               // this is to check if every factor             // of n-1 satisfy the condition             boolean flag = true;             for (i = 0; i < factors.size(); i++) {                 // if a^((n-1)/q) equal 1                 if (power(a, (n - 1) / factors.get(i), n) == 1) {                     flag = false;                     break;                 }             }               // if all condition satisfy             if (flag)                 return "prime";         }         return "probably composite";     }       // Driver code     public static void main(String[] args)     {         System.out.println(7 + " is " + lucasTest(7));         System.out.println(9 + " is " + lucasTest(9));         System.out.println(37 + " is " + lucasTest(37));     } }   // This code is contributed by phasing17

## Python3

 # Python3 program for Lucas Primality Test import random import math   # Function to generate prime factors of n def primeFactors(n, factors):           # If 2 is a factor     if (n % 2 == 0):         factors.append(2)               while (n % 2 == 0):         n = n // 2               # If prime > 2 is factor     for i in range(3, int(math.sqrt(n)) + 1, 2):         if (n % i == 0):             factors.append(i)                       while (n % i == 0):             n = n // i                   if (n > 2):         factors.append(n)               return factors       # This function produces power modulo  # some number. It can be optimized to  # using  def power(n, r, q):           total = n           for i in range(1, r):         total = (total * n) % q               return total    def lucasTest(n):        # Base cases      if (n == 1):         return "neither prime nor composite"     if (n == 2):         return "prime"     if (n % 2 == 0):         return "composite1"                # Generating and storing factors      # of n-1     factors = []           factors = primeFactors(n - 1, factors)        # Array for random generator. This array      # is to ensure one number is generated      # only once     rand = [i + 2 for i in range(n - 3)]                # Shuffle random array to produce randomness     random.shuffle(rand)        # Now one by one perform Lucas Primality     # Test on random numbers generated.     for i in range(n - 2):         a = rand[i]                    if (power(a, n - 1, n) != 1):             return "composite"            # This is to check if every factor          # of n-1 satisfy the condition         flag = True                   for k in range(len(factors)):                           # If a^((n-1)/q) equal 1             if (power(a, (n - 1) // factors[k], n) == 1):                 flag = False                 break            # If all condition satisfy         if (flag):             return "prime"           return "probably composite"       # Driver code  if __name__=="__main__":           print(str(7) + " is " + lucasTest(7))     print(str(9) + " is " + lucasTest(9))     print(str(37) + " is " + lucasTest(37))   # This code is contributed by rutvik_56

## C#

 // C# Program for Lucas Primality Test    using System; using System.Linq; using System.Collections.Generic;     class GFG {     static List<int> factors = new List<int>();     // function to generate prime factors of n      static List<int> primeFactors(int n)      {          // if 2 is a factor          if (n % 2 == 0)              factors.Add(2);          while (n % 2 == 0)              n = n / 2;                        // if prime > 2 is factor          for (int i = 3; i <= Math.Sqrt(n); i += 2) {              if (n % i == 0)                  factors.Add(i);              while (n % i == 0)                  n = n / i;          }          if (n > 2)          factors.Add(n);         return factors;     }            // this function produces power modulo      // some number. It can be optimized to      // using      static int power(int n, int r, int q)      {          int total = n;          for (int i = 1; i < r; i++)              total = (total * n) % q;          return total;      }            static string lucasTest(int n)      {          // Base cases          if (n == 1)              return "neither prime nor composite";          if (n == 2)              return "prime";          if (n % 2 == 0)              return "composite1";                                      // Generating and storing factors          // of n-1          primeFactors(n - 1);               // Array for random generator. This array          // is to ensure one number is generated          // only once          int[] random = new int[n - 2];          for (int i = 0; i < n - 2; i++)              random[i] = i + 2;                        // shuffle random array to produce randomness         Random rand = new Random();         random = random.OrderBy(x => rand.Next()).ToArray();               // Now one by one perform Lucas Primality          // Test on random numbers generated.          for (int i = 0; i < n - 2; i++) {              int a = random[i];              if (power(a, n - 1, n) != 1)                  return "composite";                    // this is to check if every factor              // of n-1 satisfy the condition              bool flag = true;              foreach (var factor in factors) {                  // if a^((n-1)/q) equal 1                  if (power(a, (n - 1) / factor, n) == 1) {                      flag = false;                      break;                  }              }                    // if all condition satisfy              if (flag)                  return "prime";          }          return "probably composite";      }            // Driver code      public static void Main(string[] args)      {          Console.WriteLine(7 + " is " + lucasTest(7));         Console.WriteLine(9 + " is " + lucasTest(9));         Console.WriteLine(37 + " is " + lucasTest(37));     }  }     // This code is contributed by phasing17

## Javascript

 // JavaScript Program for Lucas Primality Test    // A function to shuffle the array.  function shuffle(arr){     for(let i = arr.length-1; i>0;i--){         // have a random index from [0, arr.length-1]         let j = Math.floor(Math.random() * (i+1));                   // swap the original and random index element         let temp = arr[i];         arr[i] = arr[j];         arr[j] = temp;     }     return arr; }   // function to generate prime factors of n  function primeFactors(n, factors) {      // if 2 is a factor      if (n % 2 == 0){         factors.push(2);      }               while (n % 2 == 0){         n = n / 2;      }                       // if prime > 2 is factor      for (let i = 3; i <= Math.sqrt(n); i += 2) {          if (n % i == 0){             factors.push(i);          }                       while (n % i == 0){             n = n / i;          }              }      if (n > 2){         factors.push(n);      }   }    // this function produces power modulo  // some number. It can be optimized to  // using  function power(n, r, q) {      let total = n;      for (let i = 1; i < r; i++){         total = (total * n) % q;      }           return total;  }    function lucasTest(n) {           // Base cases      if (n == 1){         return "neither prime nor composite";      }           if (n == 2){        return "prime";       }           if (n % 2 == 0){         return "composite1";      }                      // Generating and storing factors      // of n-1      const factors = [];     primeFactors(n - 1, factors);        // Array for random generator. This array      // is to ensure one number is generated      // only once      const random = [];     for (let i = 0; i < n - 2; i++){         // random[i] = i + 2;          random.push(i+2);     }               // shuffle random array to produce randomness      shuffle(random);        // Now one by one perform Lucas Primality      // Test on random numbers generated.      for (let i = 0; i < n - 2; i++) {          let a = random[i];          if (power(a, n - 1, n) != 1){             return "composite";                }                       // this is to check if every factor          // of n-1 satisfy the condition          let flag = true;          for (let k = 0; k < factors.length; k++) {              // if a^((n-1)/q) equal 1              if (power(a, (n - 1) / factors[k], n) == 1) {                  flag = false;                  break;              }          }            // if all condition satisfy          if (flag){             return "prime";          }                   }      return "probably composite";  }    // Driver code  {      console.log( 7 + " is " + lucasTest(7));     console.log( 9 + " is " + lucasTest(9));     console.log( 37 + " is " + lucasTest(37));     return 0;  }    // The code is contributed by Gautam goel (gautamgoel962) Javascript

Output:

7 is prime
9 is composite
37 is prime

Time Complexity: O(nlogn)

Auxiliary Space: O(n)

This method is quite complicated and inefficient as compared to other primality tests. And the main problems are factors of â€˜n-1â€™ and choosing appropriate â€˜aâ€™.

Other Primality tests:

My Personal Notes arrow_drop_up
Related Articles