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:
#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 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)));
}
}
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
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
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)