Open In App

Find unique lexicographically increasing quadruplets with sum as B and GCD of absolute values of all elements is 1

Last Updated : 28 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A of size N and an integer B, the task is to find all unique quadruplets arranged in the lexicographically increasing order such that the sum of the elements of each quadrupled is B and the gcd of the absolute values of all elements of a quadrupled is 1.

Example:

Input: A = {1, 0, -1, 0, -2, 2 }, B = 0
Output:
-2 -1 1 2
-1  0 0 1
Explanation: There are only three unique quadruplets which have sum = 0 which are {{-2, 0, 0, 2}, {-2, -1, 1, 2}, {-1, 0, 0, 1}} and out of these quadruplets only the second and the third quadrupled have gcd equal to 1.

Input: A = { 1, 5, 1, 0, 6, 0 }, B = 7
Output:
0 0 1 6
0 1 1 5

Approach: The idea is to store the sum of each pair of elements in a hashmap, then iterate through all pairs of elements and then lookup the hashmap to find pairs such that the sum of the quadrupled becomes equal to B and the gcd of absolute values of all elements of the quadrupled is equal to 1. The detailed approach using hashmap has been discussed in this article.  Follow the steps to solve the problem.

  • Insert the sum of each pair of elements of the array into a hashmap mp.
  • Initialize a set st, to store all the quadruplets.
  • Traverse the array from i = 0 to N-1
    • Traverse the array from j = i+1 to N-1
      • Find all pairs from the hashmap whose sum is equal to B- A[i]-A[j]. Initialize a vector of pairs v to mp[B-A[i]-A[j]]. 
      • Traverse through the vector v using a variable k
        • If v[k].first or v[k].second is equal to either i or j then continue to the next iteration.
        • Store the elements of the quadrupled in a temp array. Sort the temp array. If the gcd of all elements of temp array is 1 then insert the temp array into st.
  • Traverse through the set st and print all the quadruplets.

C++14




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find all
// quadruplets with sum B.
void find4Sum(int A[], int N, int B)
{
    // Hashmap to store sum
    // of all pairs
    unordered_map<int,
                  vector<pair<int, int> > >
        mp;
 
    // Set to store all quadruplets
    set<vector<int> > st;
 
    // Traverse the array
    for (int i = 0; i < N - 1; i++) {
        // Traverse the array
        for (int j = i + 1; j < N; j++) {
            int sum = A[i] + A[j];
            // Insert sum of
            // current pair into
            // the hashmap
            mp[sum].push_back({ i, j });
        }
    }
 
    // Traverse the array
    for (int i = 0; i < N - 1; i++) {
        // Traverse the array
        for (int j = i + 1; j < N; j++) {
            int sum = A[i] + A[j];
            // Lookup the hashmap
            if (mp.find(B - sum) != mp.end()) {
                vector<pair<int, int> > v
                    = mp[B - sum];
 
                for (int k = 0; k < v.size(); k++) {
 
                    pair<int, int> it = v[k];
                    if (it.first != i && it.second != i
                        && it.first != j
                        && it.second != j) {
                        vector<int> temp;
                        temp.push_back(A[i]);
                        temp.push_back(A[j]);
                        temp.push_back(A[it.first]);
                        temp.push_back(A[it.second]);
 
                        // Stores the gcd of the
                        // quadrupled
                        int gc = abs(temp[0]);
                        gc = __gcd(abs(temp[1]), gc);
                        gc = __gcd(abs(temp[2]), gc);
                        gc = __gcd(abs(temp[3]), gc);
                        // Arrange in
                        // ascending order
                        sort(temp.begin(), temp.end());
                        // Insert into set if gcd is 1
                        if (gc == 1)
                            st.insert(temp);
                    }
                }
            }
        }
    }
    // Iterate through set
    for (auto it = st.begin(); it != st.end(); it++) {
        vector<int> temp = *it;
        // Print the elements
        for (int i = 0; i < 4; i++) {
            cout << temp[i] << " ";
        }
        cout << endl;
    }
}
 
// Driver Code
int main()
{
    // Input
    int N = 6;
    int A[6]
        = { 1, 0, -1, 0, -2, 2 };
    int B = 0;
 
    // Function Call
    find4Sum(A, N, B);
    return 0;
}


Java




import java.util.*;
 
public class Main {
    // Function to find all quadruplets with sum B.
    static void find4Sum(int[] A, int N, int B)
    {
        // Hashmap to store sum of all pairs
        Map<Integer, List<Pair<Integer, Integer> > > mp
            = new HashMap<>();
 
        // Set to store all quadruplets
        Set<List<Integer> > st = new HashSet<>();
 
        // Traverse the array
        for (int i = 0; i < N - 1; i++) {
            // Traverse the array
            for (int j = i + 1; j < N; j++) {
                int sum = A[i] + A[j];
                // Insert sum of current pair into the
                // hashmap
                if (!mp.containsKey(sum)) {
                    mp.put(sum, new ArrayList<>());
                }
                mp.get(sum).add(new Pair<>(i, j));
            }
        }
 
        // Traverse the array
        for (int i = 0; i < N - 1; i++) {
            // Traverse the array
            for (int j = i + 1; j < N; j++) {
                int sum = A[i] + A[j];
                // Lookup the hashmap
                if (mp.containsKey(B - sum)) {
                    List<Pair<Integer, Integer> > v
                        = mp.get(B - sum);
 
                    for (Pair<Integer, Integer> it : v) {
                        if (it.getKey() != i
                            && it.getValue() != i
                            && it.getKey() != j
                            && it.getValue() != j) {
                            List<Integer> temp
                                = new ArrayList<>();
                            temp.add(A[i]);
                            temp.add(A[j]);
                            temp.add(A[it.getKey()]);
                            temp.add(A[it.getValue()]);
 
                            // Stores the gcd of the
                            // quadrupled
                            int gc = Math.abs(temp.get(0));
                            gc = gcd(Math.abs(temp.get(1)),
                                     gc);
                            gc = gcd(Math.abs(temp.get(2)),
                                     gc);
                            gc = gcd(Math.abs(temp.get(3)),
                                     gc);
                            // Arrange in ascending order
                            Collections.sort(temp);
                            // Insert into set if gcd is 1
                            if (gc == 1) {
                                st.add(temp);
                            }
                        }
                    }
                }
            }
        }
        // Iterate through set
        for (List<Integer> temp : st) {
            // Print the elements
            for (int i = 0; i < 4; i++) {
                System.out.print(temp.get(i) + " ");
            }
            System.out.println();
        }
    }
 
    static int gcd(int a, int b)
    {
        if (b == 0)
            return a;
 
        else
            return gcd(b, Math.abs(a - b));
    }
 
    static class Pair<T, U> {
        T key;
        U value;
 
        public Pair(T key, U value)
        {
            this.key = key;
            this.value = value;
        }
 
        public T getKey() { return key; }
 
        public U getValue() { return value; }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Input
        int N = 6;
        int[] A = { 1, 0, -1, 0, -2, 2 };
        int B = 0;
 
        // Function Call
        find4Sum(A, N, B);
    }
}


Python3




# Python3 code for the above approach
from math import gcd
 
# Function to find all
# quadruplets with sum B.
def find4Sum( A, N, B):
   
    # Hashmap to store sum
    # of all pairs
    mp = dict()
     
    # Set to store all quadruplets
    st = set()
 
    # Traverse the array
    for i in range(N - 1):
        for j in range(i + 1, N):
            sum = A[i] + A[j]
             
            # Insert sum of
            # current pair into
            # the hashmap
            if sum not in mp:
                mp[sum] = []
            mp[sum].append([ i, j ])
         
 
    # Traverse the array
    for i in range(N - 1):
        # Traverse the array
        for j in range(i + 1, N):
             
            sum = A[i] + A[j]
            # Lookup the hashmap
            if (B - sum) in mp:
                v = mp[B - sum]
                 
                for k in range(len(v)):
                    it = v[k]
                    if it[0] != i and it[1] != i and it[0] != j and it[1] != j:
                        temp = (A[i], A[j], A[it[0]], A[it[1]])
 
                        # Stores the gcd of the
                        # quadrupled
                        gc = abs(temp[0]);
                        gc = gcd(abs(temp[1]), gc);
                        gc = gcd(abs(temp[2]), gc);
                        gc = gcd(abs(temp[3]), gc);
                         
                        # Arrange in
                        # ascending order
 
                        # Insert into set if gcd is 1
                        if (gc == 1):
                            st.add(tuple(sorted(temp)))
                             
    # Iterate through set
    for it in st:
        temp = it;
         
        # Print the elements
        print(*it)
 
# Driver Code
 
# Input
N = 6;
A = [ 1, 0, -1, 0, -2, 2 ];
B = 0;
 
# Function Call
find4Sum(A, N, B);
 
# This code is contributed by phasing17


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
 
class Program {
    static int gcd(int a, int b)
    {
        if (a == 0) {
            return b;
        }
        return gcd(b % a, a);
    }
 
    // Function to find all
    // quadruplets with sum B.
    static void find4Sum(int[] A, int N, int B)
    {
        // Hashmap to store sum of all pairs
        Dictionary<int, List<Tuple<int, int> > > mp
            = new Dictionary<int,
                             List<Tuple<int, int> > >();
 
        // Hashset to store all quadruplets
        HashSet<Tuple<int, int, int, int> > st
            = new HashSet<Tuple<int, int, int, int> >();
 
        // Traverse the array
        for (int i = 0; i < N - 1; i++) {
            for (int j = i + 1; j < N; j++) {
                int sum = A[i] + A[j];
 
                // Insert sum of current pair into the
                // hashmap
                if (!mp.ContainsKey(sum)) {
                    mp[sum] = new List<Tuple<int, int> >();
                }
                mp[sum].Add(new Tuple<int, int>(i, j));
            }
        }
 
        // Traverse the array
        for (int i = 0; i < N - 1; i++) {
            // Traverse the array
            for (int j = i + 1; j < N; j++) {
                int sum = A[i] + A[j];
                // Lookup the hashmap
                if (mp.ContainsKey(B - sum)) {
                    List<Tuple<int, int> > v = mp[B - sum];
                    foreach(Tuple<int, int> it in v)
                    {
                        if (it.Item1 != i && it.Item2 != i
                            && it.Item1 != j
                            && it.Item2 != j) {
                            Tuple<int, int, int, int> temp
                                = Tuple.Create(A[i], A[j],
                                               A[it.Item1],
                                               A[it.Item2]);
 
                            // Stores the gcd of the
                            // quadrupled
                            int gc = Math.Abs(temp.Item1);
                            gc = gcd(Math.Abs(temp.Item2),
                                     gc);
                            gc = gcd(Math.Abs(temp.Item3),
                                     gc);
                            gc = gcd(Math.Abs(temp.Item4),
                                     gc);
 
                            // Arrange in ascending order
 
                            // Insert into hashset if gcd is
                            // 1
                            if (gc == 1) {
                                int[] arr = { temp.Item1,
                                              temp.Item2,
                                              temp.Item3,
                                              temp.Item4 };
                                Array.Sort(arr);
                                st.Add(Tuple.Create(
                                    arr[0], arr[1], arr[2],
                                    arr[3]));
                            }
                        }
                    }
                }
            }
        }
 
        // Iterate through hashset
        foreach(Tuple<int, int, int, int> it in st)
        {
            // Print the elements
            Console.WriteLine("{0} {1} {2} {3}", it.Item1,
                              it.Item2, it.Item3, it.Item4);
        }
    }
 
    // Driver Code
    static void Main(string[] args)
    {
        // Input
        int N = 6;
        int[] A = { 1, 0, -1, 0, -2, 2 };
        int B = 0;
 
        // Function Call
        find4Sum(A, N, B);
    }
}
 
// This code is contributed by Pushpesh Raj.


Javascript




// Function to find gcd of two numbers
function gcd(a, b) {
  if (a === 0) {
    return b;
  }
  return gcd(b % a, a);
}
 
// Function to find all unique quadruplets with
// sum B arranged in the lexicographically increasing order
function find4Sum(A, N, B) {
  // Hashmap to store sum of all pairs
  const mp = new Map();
 
  // Set to store all quadruplets
  const st = new Set();
 
  // Traverse the array
  for (let i = 0; i < N - 1; i++) {
    for (let j = i + 1; j < N; j++) {
      const sum = A[i] + A[j];
 
      // Insert sum of current pair into the hashmap
      if (!mp.has(sum)) {
        mp.set(sum, []);
      }
      mp.get(sum).push([i, j]);
    }
  }
 
  // Traverse the array
  for (let i = 0; i < N - 1; i++) {
    // Traverse the array
    for (let j = i + 1; j < N; j++) {
      const sum = A[i] + A[j];
      // Lookup the hashmap
      if (mp.has(B - sum)) {
        const v = mp.get(B - sum);
 
        for (let k = 0; k < v.length; k++) {
          const it = v[k];
          if (
            it[0] !== i &&
            it[1] !== i &&
            it[0] !== j &&
            it[1] !== j
          ) {
            const temp = [A[i], A[j], A[it[0]], A[it[1]]];
 
            // Stores the gcd of the quadrupled
            let gc = Math.abs(temp[0]);
            gc = gcd(Math.abs(temp[1]), gc);
            gc = gcd(Math.abs(temp[2]), gc);
            gc = gcd(Math.abs(temp[3]), gc);
 
            // Arrange in ascending order
            temp.sort((a, b) => a - b);
 
            // Insert into set if gcd is 1 and the quadruplet
            // is lexicographically increasing
            if (gc === 1 && !st.has(temp.join(' '))) {
              st.add(temp.join(' '));
              console.log(...temp);
            }
          }
        }
      }
    }
  }
}
 
// Driver Code
 
// Input
const N = 6;
const A = [1, 0, -1, 0, -2, 2];
const B = 0;
 
// Function Call
find4Sum(A, N, B);


Output

-1 0 0 1
-2 -1 1 2

Time Complexity: O(N^3)
Auxiliary Space: O(N^2)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads