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++
// 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
// 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
# 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#
// 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 |
Javascript
<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)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!