Lucas Primality Test
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 <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:
- 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)
Please Login to comment...