Given a large number N, the task is to divide this number into a product of two factors, using Fermat’s Factorisation method. Examples
Input: N = 105327569 Output: 10223, 10303 Input: N = 249803 Output: 23, 10861
Fermat Factorization: Fermat’s Factorization method is based on the representation of an odd integer as the difference of two squares. For an integer N, we want a and b such as:
N = a2 - b2 = (a+b)(a-b)
where (a+b) and (a-b) are
the factors of the number N.
Approach:
- Get the number as an object of BigInteger class
- Find the square root of N.
- It is guaranteed that the value of a is greater than sqrt(N) and value of b less than sqrt(N).
- Take the value of sqrt(n) as a and increment the number until and unless a number b is found such that N – a^2 is a perfect square.
Below is the implementation of the above approach:
C++
#include <iostream> #include <string> #include <cmath> #include <stdexcept> using namespace std;
// Function to find the Floor // of square root of a number long long sqrtF( long long x)
{ // if x is less than 0
if (x < 0)
{
throw invalid_argument( "Negative argument." );
}
// if x==0 or x==1
if (x == 0 || x == 1)
{
return x;
}
long long y = x / 2;
// run a loop
while (y > x / y)
{
y = (x / y + y) / 2;
}
return y;
} // function to find the Ceil // of square root of a number long long sqrtC( long long x)
{ long long y = sqrtF(x);
if (x == y * y)
{
return y;
}
else
{
return y + 1;
}
} // Fermat factorisation string FermatFactors( long long n)
{ // if n%2 ==0 then return the factors
if (n % 2 == 0)
{
return to_string(n / 2) + ", 2" ;
}
// find the square root
long long a = sqrtC(n);
// if the number is a perfect square
if (a * a == n)
{
return to_string(a) + ", " + to_string(a);
}
// else perform factorisation
long long b;
while ( true )
{
long long b1 = a * a - n;
b = sqrtF(b1);
if (b * b == b1)
{
break ;
}
else
{
a += 1;
}
}
return to_string(a - b) + ", " + to_string(a + b);
} // Driver code int main()
{ string N = "105327569" ;
cout << FermatFactors(stoll(N)) << endl;
return 0;
} //This code is contributed by Aman |
Java
// Java program for Fermat's Factorization // method for large numbers import java.math.*;
import java.util.*;
class Solution {
// Function to find the Floor
// of square root of a number
public static BigInteger sqrtF(BigInteger x)
throws IllegalArgumentException
{
// if x is less than 0
if (x.compareTo(BigInteger.ZERO) < 0 ) {
throw new IllegalArgumentException(
"Negative argument.");
}
// if x==0 or x==1
if (x.equals(BigInteger.ZERO)
|| x.equals(BigInteger.ONE)) {
return x;
}
BigInteger two
= BigInteger.valueOf(2L);
BigInteger y;
// run a loop
y = x.divide(two);
while (y.compareTo(x.divide(y)) > 0 )
y = ((x.divide(y)).add(y))
.divide(two);
return y;
}
// function to find the Ceil
// of square root of a number
public static BigInteger sqrtC(BigInteger x)
throws IllegalArgumentException
{
BigInteger y = sqrtF(x);
if (x.compareTo(y.multiply(y)) == 0 ) {
return y;
}
else {
return y.add(BigInteger.ONE);
}
}
// Fermat factorisation
static String FermatFactors(BigInteger n)
{
// constants
BigInteger ONE = new BigInteger(" 1 ");
BigInteger ZERO = new BigInteger(" 0 ");
BigInteger TWO = new BigInteger(" 2 ");
// if n%2 ==0 then return the factors
if (n.mod(TWO).equals(ZERO)) {
return n.divide(TWO)
.toString()
+ ", 2 ";
}
// find the square root
BigInteger a = sqrtC(n);
// if the number is a perfect square
if (a.multiply(a).equals(n)) {
return a.toString()
+ ", " + a.toString();
}
// else perform factorisation
BigInteger b;
while ( true ) {
BigInteger b1 = a.multiply(a)
.subtract(n);
b = sqrtF(b1);
if (b.multiply(b).equals(b1))
break ;
else
a = a.add(ONE);
}
return a.subtract(b).toString()
+ ", " + a.add(b).toString();
}
// Driver code
public static void main(String args[])
{
String N = " 105327569 ";
System.out.println(
FermatFactors(
new BigInteger(N)));
}
} |
Python3
import math
# Function to find the Floor # of square root of a number def sqrtF(x):
# if x is less than 0
if x < 0 :
raise ValueError( "Negative argument." )
# if x==0 or x==1
if x = = 0 or x = = 1 :
return x
y = x / / 2
# run a loop
while y > x / / y:
y = (x / / y + y) / / 2
return y
# function to find the Ceil # of square root of a number def sqrtC(x):
y = sqrtF(x)
if x = = y * y:
return y
else :
return y + 1
# Fermat factorisation def FermatFactors(n):
# if n%2 ==0 then return the factors
if n % 2 = = 0 :
return str (n / / 2 ) + ", 2"
# find the square root
a = sqrtC(n)
# if the number is a perfect square
if a * a = = n:
return str (a) + ", " + str (a)
# else perform factorisation
while True :
b1 = a * a - n
b = sqrtF(b1)
if b * b = = b1:
break
else :
a + = 1
return str (a - b) + ", " + str (a + b)
# Driver code if __name__ = = "__main__" :
N = "105327569"
print (FermatFactors( int (N)))
# This code is contributed by sarojmcy2e |
C#
using System;
public class FermatFactorization
{ // Function to find the Floor
// of square root of a number
public static long SqrtF( long x)
{
// if x is less than 0
if (x < 0)
{
throw new ArgumentException( "Negative argument." );
}
// if x==0 or x==1
if (x == 0 || x == 1)
{
return x;
}
long y = x / 2;
// run a loop
while (y > x / y)
{
y = (x / y + y) / 2;
}
return y;
}
// function to find the Ceil
// of square root of a number
public static long SqrtC( long x)
{
long y = SqrtF(x);
if (x == y * y)
{
return y;
}
else
{
return y + 1;
}
}
// Fermat factorisation
public static string FermatFactors( long n)
{
// if n%2 ==0 then return the factors
if (n % 2 == 0)
{
return (n / 2) + ", 2" ;
}
// find the square root
long a = SqrtC(n);
// if the number is a perfect square
if (a * a == n)
{
return a + ", " + a;
}
// else perform factorisation
long b;
while ( true )
{
long b1 = a * a - n;
b = SqrtF(b1);
if (b * b == b1)
{
break ;
}
else
{
a += 1;
}
}
return (a - b) + ", " + (a + b);
}
// Driver code
public static void Main( string [] args)
{
string N = "105327569" ;
Console.WriteLine(FermatFactors( long .Parse(N)));
}
} // This code is contributed by Aman |
Javascript
function sqrtF(x) {
if (x < 0) {
throw new Error( "Negative argument." );
}
if (x === 0 || x === 1) {
return x;
}
let y = BigInt(x >> 1n);
while (y > BigInt(x / y)) {
y = BigInt((BigInt(x) / BigInt(y) + BigInt(y)) >> 1n);
}
return y;
} function sqrtC(x) {
const y = sqrtF(x);
if (x === y * y) {
return y;
} else {
return y + 1n;
}
} function FermatFactors(n) {
const ONE = 1n;
const ZERO = 0n;
const TWO = 2n;
if (n % TWO === ZERO) {
return `${n / TWO}, 2`;
}
const a = sqrtC(n);
if (a * a === n) {
return `${a}, ${a}`;
}
let b;
while ( true ) {
const b1 = a * a - n;
b = sqrtF(b1);
if (b * b === b1) {
break ;
} else {
a += 1n;
}
}
return `${a - b}, ${a + b}`;
} const N = "105327569" ;
console.log(FermatFactors(BigInt(N))); |
Output
10223, 10303
Performance Analysis :
Time Complexity: O(sqrt(N))
Space Complexity: O(1)