Skip to content
Related Articles

Related Articles

Improve Article

Euler’s Factorization method

  • Last Updated : 12 Jul, 2021

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)
-&gtl (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. 

  1. 221 = 112 + 102 = 52 + 142
  2. 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:  



  1. 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.
  2. Store the values in A, B, C, D.
  3. Find the values of K, H, L, and M using the formula mentioned in the above approach.
  4. 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

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>
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) 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :