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++ 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 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 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# 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 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:
- Primality Test | Set 1 (Introduction and School Method)
- Primality Test | Set 2 (Fermat Method)
- Primality Test | Set 3 (Miller–Rabin)
- Primality Test | Set 4 (Solovay-Strassen)