Given a number N, the task is to find the factors of N.
Examples:
Input: N = 1000009
Output: 293 3413
Explanation:
293 * 3413 = 1000009
Input: N = 100000
Output: 800 125
Explanation:
800 * 125 = 100000
Euler’s Factorization method: Euler’s factorization method works on the principle that all the numbers N which can be written as the sum of two powers in two different ways can be factored into two numbers, (i.e) N = A2 + B2 = C2 + D2 where A != C and A != D, then there exist two factors for N.
Working of the algorithm: Let N be the number for which we need to find the factors.
- So, initially, we need to find two ways to represent N as the sum of powers of two numbers.
N = A2 + B2 N = C2 + D2 Therefore, N = A2 + B2 = C2 + D2
- Now, the algebraic operations are performed on the above equation to convert the equations as:
N = A2 + B2 = C2 + D2 -> N = A2 - C2 = D2 - B2 -> N = (A - C)(A + C) = (D - B)(D + B)
- Let K be the GCD of (A – C) and (D – B). So,
A - C = K * L D - B = K * M where GCD(L, M) is 1.
- Clearly, L = (A – C) / K and M = (D – B)/K. On substituting this in the initial equation:
N = K * L * (A + C) = K * M * (D + B) -> L * (A + C) = M * (D + B) ->l (A + C)/(D + B) = M/L
- Therefore:
(A + C) = M * H (D + B) = L * H where, H = gcd((A + C), (D + B))
- Let Q = (K2 + H2)(L2 + M2).
-> ((KL)2 + (KM)2 + (HL)2 + (HM)2) -> ((A - C)2 + (D - B)2 + (D + B)2 + (A + C)2) -> ((2 * A)2 + (2 * B)2 + (2 * C)2 + (2 * D)2) -> 4 * N
- Therefore,
N = ((K/2)2 + (H/2)2)(L2 + M2)
- Such that there exist a pair K and H which are both even numbers.
Let’s visualize the above approach by taking an example. Let N = 221.
- 221 = 112 + 102 = 52 + 142
- From the above equation:
A = 11 - 5 = 6 B = 11 + 5 = 15 C = 14 - 10 = 4 D = 14 + 10 = 24
- Therefore, the above values can be used to compute the values of K, H, L, and M.
K = GCD(6, 4) = 2 H = GCD(16, 24) = 8 L = GCD(6, 24) = 3 M = GCD(16, 4) = 2
- Therefore:
221 = ((2/2)2 + (8/2)2) * (32 + 22) 221 = 17 * 13
Approach: In order to implement the above approach, the following steps are computed:
- Find the sum of squares by iterating a loop from 1 to sqrt(N) because no factor exists between [sqrt(N), N] apart from N and find two pairs whose sum of squares is equal to N.
- Store the values in A, B, C, D.
- Find the values of K, H, L, and M using the formula mentioned in the above approach.
- Use the values of K, H, L, and M to find the factors. Check the pair where both the numbers are even and divide them in half and find the factors.
Below is the implementation of the above approach:
// C++ program to implement Eulers // Factorization algorithm #include <bits/stdc++.h> using namespace std;
// Function to return N as the sum of // two squares in two possible ways void sumOfSquares( int n, vector<pair< int , int > >& vp)
{ // Iterate a loop from 1 to sqrt(n)
for ( int i = 1; i <= sqrt (n); i++) {
// If i*i is square check if there
// exists another integer such that
// h is a perfect square and i*i + h = n
int h = n - i * i, h1 = sqrt (h);
// If h is perfect square
if (h1 * h1 == h) {
// Store in the sorted way
int a = max(h1, i), b = min(h1, i);
// If there is already a pair
// check if pairs are equal or not
if (vp.size() == 1 && a != vp[0].first)
vp.push_back(make_pair(a, b));
// Insert the first pair
if (vp.size() == 0)
vp.push_back(make_pair(a, b));
// If two pairs are found
if (vp.size() == 2)
return ;
}
}
} // Function to find the factors void findFactors( int n)
{ // Get pairs where a^2 + b^2 = n
vector<pair< int , int > > vp;
sumOfSquares(n, vp);
// Number cannot be represented
// as sum of squares in two ways
if (vp.size() != 2)
cout << "Factors Not Possible" ;
// Assign a, b, c, d
int a, b, c, d;
a = vp[0].first;
b = vp[0].second;
c = vp[1].first;
d = vp[1].second;
// Swap if a < c because
// if a - c < 0,
// GCD cant be computed.
if (a < c) {
int t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
}
// Compute the values of k, h, l, m
// using the formula mentioned
// in the approach
int k, h, l, m;
k = __gcd(a - c, d - b);
h = __gcd(a + c, d + b);
l = (a - c) / k;
m = (d - b) / k;
// Print the values of a, b, c, d
// and k, l, m, h
cout << "a = " << a
<< "\t\t(A) a - c = " << (a - c)
<< "\t\tk = gcd[A, C] = "
<< k << endl;
cout << "b = " << b
<< "\t\t(B) a + c = " << (a + c)
<< "\t\th = gcd[B, D] = "
<< h << endl;
cout << "c = " << c
<< "\t\t(C) d - b = " << (d - b)
<< "\t\tl = A/k = "
<< l << endl;
cout << "d = " << d
<< "\t\t(D) d + b = " << (d + b)
<< "\t\tm = c/k = "
<< m << endl;
// Printing the factors
if (k % 2 == 0 && h % 2 == 0) {
k = k / 2;
h = h / 2;
cout << "Factors are: "
<< ((k) * (k) + (h) * (h))
<< " " << (l * l + m * m)
<< endl;
}
else {
l = l / 2;
m = m / 2;
cout << "Factors are: "
<< ((l) * (l) + (m) * (m))
<< " " << (k * k + h * h)
<< endl;
}
} // Driver code int main()
{ int n = 100000;
findFactors(n);
return 0;
} |
// Java program to implement Eulers // Factorization algorithm import java.util.*;
class GFG{
static class pair
{ int first, second;
public pair( int first,
int second)
{
this .first = first;
this .second = second;
}
} // Recursive function to // return gcd of a and b static int __gcd( int a, int b)
{ return b == 0 ? a :
__gcd(b, a % b);
} // Function to return N as the sum of // two squares in two possible ways static void sumOfSquares( int n,
Vector<pair> vp)
{ // Iterate a loop from 1 to Math.sqrt(n)
for ( int i = 1 ; i <= Math.sqrt(n); i++)
{
// If i*i is square check if there
// exists another integer such that
// h is a perfect square and i*i + h = n
int h = n - i * i, h1 = ( int )Math.sqrt(h);
// If h is perfect square
if (h1 * h1 == h)
{
// Store in the sorted way
int a = Math.max(h1, i),
b = Math.min(h1, i);
// If there is already a pair
// check if pairs are equal or not
if (vp.size() == 1 &&
a != vp.get( 0 ).first)
vp.add( new pair(a, b));
// Insert the first pair
if (vp.size() == 0 )
vp.add( new pair(a, b));
// If two pairs are found
if (vp.size() == 2 )
return ;
}
}
} // Function to find the factors static void findFactors( int n)
{ // Get pairs where a^2 + b^2 = n
Vector<pair> vp = new Vector<>();
sumOfSquares(n, vp);
// Number cannot be represented
// as sum of squares in two ways
if (vp.size() != 2 )
System.out.print( "Factors Not Possible" );
// Assign a, b, c, d
int a, b, c, d;
a = vp.get( 0 ).first;
b = vp.get( 0 ).second;
c = vp.get( 1 ).first;
d = vp.get( 1 ).second;
// Swap if a < c because
// if a - c < 0,
// GCD cant be computed.
if (a < c)
{
int t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
}
// Compute the values of k, h, l, m
// using the formula mentioned
// in the approach
int k, h, l, m;
k = __gcd(a - c, d - b);
h = __gcd(a + c, d + b);
l = (a - c) / k;
m = (d - b) / k;
// Print the values of a, b, c, d
// and k, l, m, h
System.out.print( "a = " + a +
"\t\t(A) a - c = " +
(a - c) +
"\t\tk = gcd[A, C] = " +
k + "\n" );
System.out.print( "b = " + b +
"\t\t(B) a + c = " +
(a + c) +
"\t\th = gcd[B, D] = " +
h + "\n" );
System.out.print( "c = " + c +
"\t\t(C) d - b = " +
(d - b) +
"\t\tl = A/k = " +
l + "\n" );
System.out.print( "d = " + d +
"\t\t(D) d + b = " +
(d + b) +
"\t\tm = c/k = " +
m + "\n" );
// Printing the factors
if (k % 2 == 0 && h % 2 == 0 )
{
k = k / 2 ;
h = h / 2 ;
System.out.print( "Factors are: " +
((k) * (k) + (h) * (h)) +
" " + (l * l + m * m) + "\n" );
}
else
{
l = l / 2 ;
m = m / 2 ;
System.out.print( "Factors are: " +
((l) * (l) + (m) * (m)) +
" " + (k * k + h * h) + "\n" );
}
} // Driver code public static void main(String[] args)
{ int n = 100000 ;
findFactors(n);
} } // This code is contributed by gauravrajput1 |
# Python3 program to implement Eulers # Factorization algorithm from math import gcd
# Function to return N as the sum of # two squares in two possible ways def sumOfSquares(n, vp):
# Iterate a loop from 1 to Math.sqrt(n)
for i in range ( 1 , 1 + int (n * * 0.5 )):
# If i*i is square check if there
# exists another integer such that
# h is a perfect square and i*i + h = n
h = n - i * i
h1 = int (h * * 0.5 )
# If h is perfect square
if (h1 * h1 = = h):
# Store in the sorted way
a = max (h1, i)
b = min (h1, i);
# If there is already a pair
# check if pairs are equal or not
if ( len (vp) = = 1 and a ! = vp[ 0 ][ 0 ]):
vp.append([a, b]);
# Insert the first pair
if ( len (vp) = = 0 ):
vp.append([a, b]);
# If two pairs are found
if ( len (vp) = = 2 ):
return ;
# Function to find the factors def findFactors(n):
# Get pairs where a^2 + b^2 = n
vp = [];
sumOfSquares(n, vp);
# Number cannot be represented
# as sum of squares in two ways
if ( len (vp) ! = 2 ):
print ( "Factors Not Possible" );
a = vp[ 0 ][ 0 ]
b = vp[ 0 ][ 1 ];
c = vp[ 1 ][ 0 ];
d = vp[ 1 ][ 1 ];
# Swap if a < c because
# if a - c < 0,
# GCD cant be computed.
if (a < c):
t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
# Compute the values of k, h, l, m
# using the formula mentioned
# in the approach
k = gcd(a - c, d - b);
h = gcd(a + c, d + b);
l = (a - c) / / k;
m = (d - b) / / k;
# Print the values of a, b, c, d
# and k, l, m, h
print ( "a = " , a, " (A) a - c = " , (a - c), " k = gcd[A, C] = " , sep = "");
print ( "b = " , b, " (B) a + c = " , (a + c), " h = gcd[B, D] = " , h, sep = "");
print ( "c = " , c, " (C) d - b = " , (d - b), " l = A/k = " , l, sep = "");
print ( "d = " , d, " (D) d + b = " , (d + b), " m = c/k = " , m, sep = "");
# Printing the factors
if (k % 2 = = 0 and h % 2 = = 0 ):
k = k / 2
h / = 2
print ( "Factors are: " , ((k) * (k) + (h) * (h)), " " , (l * l + m * m), sep = "" );
else :
l = l / 2 ;
m = m / 2 ;
print ( "Factors are: " , ((l) * (l) + (m) * (m)), " " , (k * k + h * h), sep = "" );
# Driver code n = 100000 ;
findFactors(n); # This code is contributed by phasing17 |
// C# program to implement Eulers // Factorization algorithm using System;
using System.Collections.Generic;
class GFG{
public class pair
{ public int first, second;
public pair( int first,
int second)
{
this .first = first;
this .second = second;
}
} // Recursive function to // return gcd of a and b static int __gcd( int a, int b)
{ return b == 0 ? a :
__gcd(b, a % b);
} // Function to return N as the sum of // two squares in two possible ways static void sumOfSquares( int n,
List<pair> vp)
{ // Iterate a loop from 1 to Math.Sqrt(n)
for ( int i = 1; i <= Math.Sqrt(n); i++)
{
// If i*i is square check if there
// exists another integer such that
// h is a perfect square and i*i + h = n
int h = n - i * i, h1 = ( int )Math.Sqrt(h);
// If h is perfect square
if (h1 * h1 == h)
{
// Store in the sorted way
int a = Math.Max(h1, i),
b = Math.Min(h1, i);
// If there is already a pair
// check if pairs are equal or not
if (vp.Count == 1 &&
a != vp[0].first)
vp.Add( new pair(a, b));
// Insert the first pair
if (vp.Count == 0)
vp.Add( new pair(a, b));
// If two pairs are found
if (vp.Count == 2)
return ;
}
}
} // Function to find the factors static void findFactors( int n)
{ // Get pairs where a^2 + b^2 = n
List<pair> vp = new List<pair>();
sumOfSquares(n, vp);
// Number cannot be represented
// as sum of squares in two ways
if (vp.Count != 2)
Console.Write( "Factors Not Possible" );
// Assign a, b, c, d
int a, b, c, d;
a = vp[0].first;
b = vp[0].second;
c = vp[1].first;
d = vp[1].second;
// Swap if a < c because
// if a - c < 0,
// GCD cant be computed.
if (a < c)
{
int t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
}
// Compute the values of k, h, l, m
// using the formula mentioned
// in the approach
int k, h, l, m;
k = __gcd(a - c, d - b);
h = __gcd(a + c, d + b);
l = (a - c) / k;
m = (d - b) / k;
// Print the values of a, b, c, d
// and k, l, m, h
Console.Write( "a = " + a +
"\t\t(A) a - c = " +
(a - c) +
"\t\tk = gcd[A, C] = " +
k + "\n" );
Console.Write( "b = " + b +
"\t\t(B) a + c = " +
(a + c) +
"\t\th = gcd[B, D] = " +
h + "\n" );
Console.Write( "c = " + c +
"\t\t(C) d - b = " +
(d - b) +
"\t\tl = A/k = " +
l + "\n" );
Console.Write( "d = " + d +
"\t\t(D) d + b = " +
(d + b) +
"\t\tm = c/k = " +
m + "\n" );
// Printing the factors
if (k % 2 == 0 && h % 2 == 0)
{
k = k / 2;
h = h / 2;
Console.Write( "Factors are: " +
((k) * (k) + (h) * (h)) +
" " + (l * l + m * m) + "\n" );
}
else
{
l = l / 2;
m = m / 2;
Console.Write( "Factors are: " +
((l) * (l) + (m) * (m)) +
" " + (k * k + h * h) + "\n" );
}
} // Driver code public static void Main(String[] args)
{ int n = 100000;
findFactors(n);
} } // This code is contributed by gauravrajput1 |
<script> // JavaScript program to implement Eulers // Factorization algorithm class pair { constructor(first,second)
{
this .first = first;
this .second = second;
}
} // Recursive function to // return gcd of a and b function __gcd(a,b)
{ return b == 0 ? a :
__gcd(b, a % b);
} // Function to return N as the sum of // two squares in two possible ways function sumOfSquares(n,vp)
{ // Iterate a loop from 1 to Math.sqrt(n)
for (let i = 1; i <= Math.sqrt(n); i++)
{
// If i*i is square check if there
// exists another integer such that
// h is a perfect square and i*i + h = n
let h = n - i * i, h1 = Math.floor(Math.sqrt(h));
// If h is perfect square
if (h1 * h1 == h)
{
// Store in the sorted way
let a = Math.max(h1, i),
b = Math.min(h1, i);
// If there is already a pair
// check if pairs are equal or not
if (vp.length == 1 &&
a != vp[0].first)
vp.push( new pair(a, b));
// Insert the first pair
if (vp.length == 0)
vp.push( new pair(a, b));
// If two pairs are found
if (vp.length == 2)
return ;
}
}
} // Function to find the factors function findFactors(n)
{ // Get pairs where a^2 + b^2 = n
let vp = [];
sumOfSquares(n, vp);
// Number cannot be represented
// as sum of squares in two ways
if (vp.length != 2)
document.write( "Factors Not Possible" );
// Assign a, b, c, d
let a, b, c, d;
a = vp[0].first;
b = vp[0].second;
c = vp[1].first;
d = vp[1].second;
// Swap if a < c because
// if a - c < 0,
// GCD cant be computed.
if (a < c)
{
let t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
}
// Compute the values of k, h, l, m
// using the formula mentioned
// in the approach
let k, h, l, m;
k = __gcd(a - c, d - b);
h = __gcd(a + c, d + b);
l = (a - c) / k;
m = (d - b) / k;
// Print the values of a, b, c, d
// and k, l, m, h
document.write( "a = " + a +
"       (A) a - c = " +
(a - c) +
"      k = gcd[A, C] = " +
k + "<br>" );
document.write( "b = " + b +
"      (B) a + c = " +
(a + c) +
"      h = gcd[B, D] = " +
h + "<br>" );
document.write( "c = " + c +
"      (C) d - b = " +
(d - b) +
"      l = A/k = " +
l + "<br>" );
document.write( "d = " + d +
"      (D) d + b = " +
(d + b) +
"      m = c/k = " +
m + "<br>" );
// Printing the factors
if (k % 2 == 0 && h % 2 == 0)
{
k = k / 2;
h = h / 2;
document.write( "Factors are: " +
((k) * (k) + (h) * (h)) +
" " + (l * l + m * m) + "<br>" );
}
else
{
l = l / 2;
m = m / 2;
document.write( "Factors are: " +
((l) * (l) + (m) * (m)) +
" " + (k * k + h * h) + "<br>" );
}
} // Driver code let n = 100000; findFactors(n); // This code is contributed by unknown2108 </script> |
a = 316 (A) a - c = 16 k = gcd[A, C] = 8 b = 12 (B) a + c = 616 h = gcd[B, D] = 56 c = 300 (C) d - b = 88 l = A/k = 2 d = 100 (D) d + b = 112 m = c/k = 11 Factors are: 800 125
Complexity Analysis:
Time Complexity: O(sqrt(N)), where N is the given number
Space Complexity: O(1)