Saturday, January 11, 2025
Google search engine
HomeData Modelling & AIEuler’s Factorization method

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)
-&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 +
                   " &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp(A) a - c = " +
                   (a - c) +
                   "&nbsp&nbsp&nbsp&nbsp&nbsp&nbspk = gcd[A, C] = " +
                   k + "<br>");
  
  document.write("b = " + b +
                   "&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp(B) a + c = " +
                   (a + c) +
                   "&nbsp&nbsp&nbsp&nbsp&nbsp&nbsph = gcd[B, D] = " +
                   h + "<br>");
  
  document.write("c = " +  c +
                   "&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp(C) d - b = " +
                   (d - b) +
                   "&nbsp&nbsp&nbsp&nbsp&nbsp&nbspl = A/k = " +
                   l + "<br>");
  
  document.write("d = " +  d +
                   "&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp(D) d + b = " +
                   (d + b) +
                   "&nbsp&nbsp&nbsp&nbsp&nbsp&nbspm = 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) 

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments