Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Lucas Primality Test

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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 : 

a^{{n-1}}\ \equiv \ 1{\pmod n}

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

a^{{({n-1})/q}}\ \not \equiv \ 1{\pmod n}

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 <bits/stdc++.h>
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<Integer> factors
        = new ArrayList<Integer>();
   
    // function to generate prime factors of n
    static ArrayList<Integer> 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
Last Updated : 29 Jul, 2022
Like Article
Save Article
Similar Reads
Related Tutorials