Open In App

Euler’s Factorization method

Improve
Improve
Like Article
Like
Save
Share
Report

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


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>


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
Previous
Next
Share your thoughts in the comments
Similar Reads