Euler’s Factorization method
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
(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
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
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++
#include <bits/stdc++.h>
using namespace std;
void sumOfSquares( int n, vector<pair< int , int > >& vp)
{
for ( int i = 1; i <= sqrt (n); i++) {
int h = n - i * i, h1 = sqrt (h);
if (h1 * h1 == h) {
int a = max(h1, i), b = min(h1, i);
if (vp.size() == 1 && a != vp[0].first)
vp.push_back(make_pair(a, b));
if (vp.size() == 0)
vp.push_back(make_pair(a, b));
if (vp.size() == 2)
return ;
}
}
}
void findFactors( int n)
{
vector<pair< int , int > > vp;
sumOfSquares(n, vp);
if (vp.size() != 2)
cout << "Factors Not Possible" ;
int a, b, c, d;
a = vp[0].first;
b = vp[0].second;
c = vp[1].first;
d = vp[1].second;
if (a < c) {
int t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
}
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;
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;
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;
}
}
int main()
{
int n = 100000;
findFactors(n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair( int first,
int second)
{
this .first = first;
this .second = second;
}
}
static int __gcd( int a, int b)
{
return b == 0 ? a :
__gcd(b, a % b);
}
static void sumOfSquares( int n,
Vector<pair> vp)
{
for ( int i = 1 ; i <= Math.sqrt(n); i++)
{
int h = n - i * i, h1 = ( int )Math.sqrt(h);
if (h1 * h1 == h)
{
int a = Math.max(h1, i),
b = Math.min(h1, i);
if (vp.size() == 1 &&
a != vp.get( 0 ).first)
vp.add( new pair(a, b));
if (vp.size() == 0 )
vp.add( new pair(a, b));
if (vp.size() == 2 )
return ;
}
}
}
static void findFactors( int n)
{
Vector<pair> vp = new Vector<>();
sumOfSquares(n, vp);
if (vp.size() != 2 )
System.out.print( "Factors Not Possible" );
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;
if (a < c)
{
int t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
}
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;
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" );
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" );
}
}
public static void main(String[] args)
{
int n = 100000 ;
findFactors(n);
}
}
|
Python3
from math import gcd
def sumOfSquares(n, vp):
for i in range ( 1 , 1 + int (n * * 0.5 )):
h = n - i * i
h1 = int (h * * 0.5 )
if (h1 * h1 = = h):
a = max (h1, i)
b = min (h1, i);
if ( len (vp) = = 1 and a ! = vp[ 0 ][ 0 ]):
vp.append([a, b]);
if ( len (vp) = = 0 ):
vp.append([a, b]);
if ( len (vp) = = 2 ):
return ;
def findFactors(n):
vp = [];
sumOfSquares(n, vp);
if ( len (vp) ! = 2 ):
print ( "Factors Not Possible" );
a = vp[ 0 ][ 0 ]
b = vp[ 0 ][ 1 ];
c = vp[ 1 ][ 0 ];
d = vp[ 1 ][ 1 ];
if (a < c):
t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
k = gcd(a - c, d - b);
h = gcd(a + c, d + b);
l = (a - c) / / k;
m = (d - b) / / k;
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 = "");
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 = "" );
n = 100000 ;
findFactors(n);
|
C#
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;
}
}
static int __gcd( int a, int b)
{
return b == 0 ? a :
__gcd(b, a % b);
}
static void sumOfSquares( int n,
List<pair> vp)
{
for ( int i = 1; i <= Math.Sqrt(n); i++)
{
int h = n - i * i, h1 = ( int )Math.Sqrt(h);
if (h1 * h1 == h)
{
int a = Math.Max(h1, i),
b = Math.Min(h1, i);
if (vp.Count == 1 &&
a != vp[0].first)
vp.Add( new pair(a, b));
if (vp.Count == 0)
vp.Add( new pair(a, b));
if (vp.Count == 2)
return ;
}
}
}
static void findFactors( int n)
{
List<pair> vp = new List<pair>();
sumOfSquares(n, vp);
if (vp.Count != 2)
Console.Write( "Factors Not Possible" );
int a, b, c, d;
a = vp[0].first;
b = vp[0].second;
c = vp[1].first;
d = vp[1].second;
if (a < c)
{
int t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
}
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;
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" );
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" );
}
}
public static void Main(String[] args)
{
int n = 100000;
findFactors(n);
}
}
|
Javascript
<script>
class pair
{
constructor(first,second)
{
this .first = first;
this .second = second;
}
}
function __gcd(a,b)
{
return b == 0 ? a :
__gcd(b, a % b);
}
function sumOfSquares(n,vp)
{
for (let i = 1; i <= Math.sqrt(n); i++)
{
let h = n - i * i, h1 = Math.floor(Math.sqrt(h));
if (h1 * h1 == h)
{
let a = Math.max(h1, i),
b = Math.min(h1, i);
if (vp.length == 1 &&
a != vp[0].first)
vp.push( new pair(a, b));
if (vp.length == 0)
vp.push( new pair(a, b));
if (vp.length == 2)
return ;
}
}
}
function findFactors(n)
{
let vp = [];
sumOfSquares(n, vp);
if (vp.length != 2)
document.write( "Factors Not Possible" );
let a, b, c, d;
a = vp[0].first;
b = vp[0].second;
c = vp[1].first;
d = vp[1].second;
if (a < c)
{
let t = a;
a = c;
c = t;
t = b;
b = d;
d = t;
}
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;
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>" );
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>" );
}
}
let n = 100000;
findFactors(n);
</script>
|
Output:
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)
Last Updated :
16 Sep, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...