Open In App

Sort permutation of N natural numbers using triple cyclic right swaps

Given an array arr[] of size N which contains the permutations of the N natural numbers, the task is to sort the permutations of N natural numbers with the help of triple cyclic right swaps.

Triple Cyclic Right Swaps: refers to the triple cyclic right shift in which – 

arr[i] -> arr[j] -> arr[k] -> arr[i]

Examples:  

Input: arr[] = {3, 2, 4, 1} 
Output:
1 3 4 
Explanation: 
In the operation 1 the index 1, 3 and 4 are chosen and they are cyclic shifted – 
arr[1] = arr[4] = 1 
arr[3] = arr[1] = 3 
arr[4] = arr[3] = 4 
Therefore, final array will be {1, 2, 3, 4}.

Input: arr[] = {2, 3, 1} 
Output:
1 2 3  

Approach: The idea is to traverse the array and find the elements of the array which is not in its actual sorted position which can be checked by if . Because there are only N natural elements in the array. Finally, find the odd length cyclic rotations required in the array to get the sorted form of the array. If there is any even length cyclic rotations required then it is not possible to sort the elements of the array.

Below is the implementation of the above approach:  

// C++ implementation to find the
// number of operations required to
// sort the elements of the array
 
#include <bits/stdc++.h>
using namespace std;
#define ll long long
 
// Function to sort the permutation
// with the given operations
void sortPermutation(ll arr[], ll n)
{
    vector<pair<ll,
                pair<ll, ll> > >
        ans;
    vector<ll> p;
 
    // Visited array to check the
    // array element is at correct
    // position or not
    bool visited[200005] = { 0 };
 
    // Loop to iterate over the elements
    // of the given array
    for (ll i = 1; i <= n; i++) {
 
        // Condition to check if the
        // elements is at its correct
        // position
        if (arr[i] == i) {
            visited[i] = 1;
            continue;
        }
        else {
 
            // Condition to check if the
            // element is included in any
            // previous cyclic rotations
            if (!visited[i]) {
                ll x = i;
                vector<ll> v;
 
                // Loop to find the cyclic
                // rotations in required
                while (!visited[x]) {
                    visited[x] = 1;
                    v.push_back(x);
                    x = arr[x];
                }
 
                // Condition to check if the
                // cyclic rotation is a
                // valid rotation
                if ((v.size() - 3) % 2 == 0) {
                    for (ll i = 1; i < v.size();
                         i += 2) {
 
                        ans
                            .push_back(
                                make_pair(
                                    v[0],
                                    make_pair(
                                        v[i], v[i + 1])));
                    }
                    continue;
                }
                p.push_back(v[0]);
                p.push_back(v[v.size() - 1]);
 
                // Loop to find the index of the
                // cyclic rotation
                // for the current index
                for (ll i = 1; i < v.size() - 1;
                     i += 2) {
                    ans
                        .push_back(
                            make_pair(
                                v[0],
                                make_pair(
                                    v[i], v[i + 1])));
                }
            }
        }
    }
 
    // Condition to if the cyclic
    // rotation is a valid rotation
    if (p.size() % 4) {
        cout << -1 << "\n";
        return;
    }
 
    // Loop to find all the valid operations
    // required to sort the permutation
    for (ll i = 0; i < p.size(); i += 4) {
        ans.push_back(
            make_pair(p[i],
                      make_pair(p[i + 1], p[i + 2])));
        ans.push_back(
            make_pair(p[i + 2],
                      make_pair(p[i], p[i + 3])));
    }
 
    // Total operation required
    cout << ans.size() << "\n";
    for (ll i = 0; i < ans.size(); i++) {
        cout << ans[i].first << " "
             << ans[i].second.first << " "
             << ans[i].second.second << "\n";
    }
}
 
// Driver Code
int main()
{
    ll arr[] = { 0, 3, 2, 4, 1 };
    ll n = 4;
 
    // Function Call
    sortPermutation(arr, n);
    return 0;
}

                    
/*package whatever //do not write package name here */
import java.util.*;
 
class GFG {
 
  static class Pair{
 
    long first;
    PairL second;
 
    Pair(long f,PairL s){
      first = f;
      second = s;
    }
 
  }
 
  static class PairL{
    long first;
    long second;
 
    PairL(long f,long s){
      first = f;
      second = s;
    }
 
  }
 
  // Function to sort the permutation
  // with the given operations
  static void sortPermutation(long arr[], long n)
  {
    List<Pair> ans = new ArrayList<>();
    List<Long> p = new ArrayList<>();
 
    // Visited array to check the
    // array element is at correct
    // position or not
    boolean visited[] = new boolean[200005];
 
    // Loop to iterate over the elements
    // of the given array
    for (int i = 1; i <= n; i++) {
 
      // Condition to check if the
      // elements is at its correct
      // position
      if (arr[i] == i) {
        visited[i] = true;
        continue;
      }
      else {
 
        // Condition to check if the
        // element is included in any
        // previous cyclic rotations
        if (!visited[i]) {
          long x = i;
          List<Long> v = new ArrayList<>();
 
          // Loop to find the cyclic
          // rotations in required
          while (!visited[(int)x]) {
            visited[(int)x] = true;
            v.add(x);
            x = arr[(int)x];
          }
 
          // Condition to check if the
          // cyclic rotation is a
          // valid rotation
          if ((v.size() - 3) % 2 == 0) {
            for (int j = 1; j < v.size();j += 2) {
 
              ans.add(new Pair(v.get(0),new PairL(v.get(j), v.get(j+1))));
            }
            continue;
          }
          p.add(v.get(0));
          p.add(v.get(v.size() - 1));
 
          // Loop to find the index of the
          // cyclic rotation
          // for the current index
          for (int j = 1; j < v.size() - 1;j += 2) {
            ans.add(new Pair(v.get(0),new PairL(v.get(j), v.get(j+1))));
          }
        }
      }
    }
 
    // Condition to if the cyclic
    // rotation is a valid rotation
    if (p.size() % 4==1) {
      System.out.println("-1");
      return;
    }
 
    // Loop to find all the valid operations
    // required to sort the permutation
    for (int i = 0; i < p.size(); i += 4) {
      ans.add(new Pair(p.get(i),new PairL(p.get(i + 1), p.get(i + 2))));
      ans.add(new Pair(p.get(i+2),new PairL(p.get(i), p.get(i+3))));
    }
 
    // Total operation required
    System.out.println(ans.size());
 
    for (int i = 0; i < ans.size(); i++) {
      System.out.println(ans.get(i).first + " "+ ans.get(i).second.first + " " + ans.get(i).second.second);
    }
  }
  public static void main (String[] args) {
 
    long arr[] = { 0, 3, 2, 4, 1 };
    long n = 4;
 
    // Function Call
    sortPermutation(arr, n);
 
  }
}
 
// This code is contributed by aadityaburujwale.

                    
# Python3 implementation to find the
# number of operations required to
# sort the elements of the array
 
# Function to sort the permutation
# with the given operations
def sortPermutation(arr, n):
 
    ans = []
    p = []
 
    # Visited array to check the
    # array element is at correct
    # position or not
    visited = [0] * 200005
 
    # Loop to iterate over the elements
    # of the given array
    for i in range(1, n + 1):
 
        # Condition to check if the
        # elements is at its correct
        # position
        if (arr[i] == i):
            visited[i] = 1
            continue
 
        else:
 
            # Condition to check if the
            # element is included in any
            # previous cyclic rotations
            if (visited[i]==False):
                x = i
                v = []
 
                # Loop to find the cyclic
                # rotations in required
                while (visited[x] == False):
                    visited[x] = 1
                    v.append(x)
                    x = arr[x]
 
                # Condition to check if the
                # cyclic rotation is a
                # valid rotation
                if ((len(v) - 3) % 2 == 0):
                    for i in range(1, len(v), 2):
                        ans.append([v[0], v[i], v[i + 1]])
                    continue
 
                p.append(v[0])
                p.append(v[len(v) - 1])
 
                # Loop to find the index of the
                # cyclic rotation
                # for the current index
                for i in range(1, len(v) - 1, 2):
                    ans.append([v[0], v[i], v[i + 1]])
 
    # Condition to if the cyclic
    # rotation is a valid rotation
    if (len(p) % 4):
        print(-1)
        return
 
    # Loop to find the valid operations
    # required to sort the permutation
    for i in range(0, len(p), 4):
        ans.append([p[i], p[i + 1], p[i + 2]])
        ans.append(p[i [+ 2], p[i], p[i + 3]])
 
    # Total operation required
    print(len(ans))
    for i in ans:
        print(i[0], i[1], i[2])
 
# Driver Code
if __name__ == '__main__':
    arr=[0, 3, 2, 4, 1]
    n = 4
 
    # Function Call
    sortPermutation(arr, n)
 
# This code is contributed by Mohit Kumar

                    
// package whatever //do not write package name here
using System;
using System.Collections.Generic;
 
public class GFG {
 
    public class PairL {
        public long first;
        public long second;
 
        public PairL(long f, long s)
        {
            first = f;
            second = s;
        }
    }
 
    public class Pair {
 
        public long first;
        public PairL second;
 
        public Pair(long f, PairL s)
        {
            first = f;
            second = s;
        }
    }
 
    // Function to sort the permutation
    // with the given operations
    static void sortPermutation(long[] arr, long n)
    {
        List<Pair> ans = new List<Pair>();
        List<long> p = new List<long>();
 
        // Visited array to check the
        // array element is at correct
        // position or not
        bool[] visited = new bool[200005];
 
        // Loop to iterate over the elements
        // of the given array
        for (int i = 1; i <= n; i++) {
 
            // Condition to check if the
            // elements is at its correct
            // position
            if (arr[i] == i) {
                visited[i] = true;
                continue;
            }
            else {
 
                // Condition to check if the
                // element is included in any
                // previous cyclic rotations
                if (!visited[i]) {
                    long x = i;
                    List<long> v = new List<long>();
 
                    // Loop to find the cyclic
                    // rotations in required
                    while (!visited[(int)x]) {
                        visited[(int)x] = true;
                        v.Add(x);
                        x = arr[(int)x];
                    }
 
                    // Condition to check if the
                    // cyclic rotation is a
                    // valid rotation
                    if ((v.Count - 3) % 2 == 0) {
                        for (int j = 1; j < v.Count;
                             j += 2) {
 
                            ans.Add(new Pair(
                                v[0],
                                new PairL(v[j], v[j + 1])));
                        }
                        continue;
                    }
                    p.Add(v[0]);
                    p.Add(v[v.Count - 1]);
 
                    // Loop to find the index of the
                    // cyclic rotation
                    // for the current index
                    for (int j = 1; j < v.Count - 1;
                         j += 2) {
                        ans.Add(new Pair(
                            v[0],
                            new PairL(v[j], v[j + 1])));
                    }
                }
            }
        }
 
        // Condition to if the cyclic
        // rotation is a valid rotation
        if (p.Count % 4 == 1) {
            Console.WriteLine("-1");
            return;
        }
 
        // Loop to find all the valid operations
        // required to sort the permutation
        for (int i = 0; i < p.Count; i += 4) {
            ans.Add(new Pair(
                p[i], new PairL(p[i + 1], p[i + 2])));
            ans.Add(new Pair(p[i + 2],
                             new PairL(p[i], p[i + 3])));
        }
 
        // Total operation required
        Console.WriteLine(ans.Count);
 
        for (int i = 0; i < ans.Count; i++) {
            Console.WriteLine(ans[i].first + " "
                              + ans[i].second.first + " "
                              + ans[i].second.second);
        }
    }
    static public void Main()
    {
 
        long[] arr = { 0, 3, 2, 4, 1 };
        long n = 4;
 
        // Function Call
        sortPermutation(arr, n);
    }
}
// contributed by akashish__

                    
// JavaScript implementation to find the
// number of operations required to
// sort the elements of the array
const sortPermutation = (arr, n) => {
  let ans = [];
  let p = [];
 
  // Visited array to check the
  // array element is at correct
  // position or not
  let visited = new Array(200005).fill(0);
 
  // Loop to iterate over the elements
  // of the given array
  for (let i = 1; i <= n; i++) {
 
    // Condition to check if the
    // elements is at its correct
    // position
    if (arr[i] === i) {
      visited[i] = 1;
      continue;
    }
    else {
 
      // Condition to check if the
      // element is included in any
      // previous cyclic rotations
      if (!visited[i]) {
        let x = i;
        let v = [];
 
        // Loop to find the cyclic
        // rotations in required
        while (!visited[x]) {
          visited[x] = 1;
          v.push(x);
          x = arr[x];
        }
 
        // Condition to check if the
        // cyclic rotation is a
        // valid rotation
        if ((v.length - 3) % 2 === 0) {
          for (let i = 1; i < v.length;
            i += 2) {
 
            ans
              .push(
                [v[0],
                [v[i], v[i + 1]]]);
          }
          continue;
        }
        p.push(v[0]);
        p.push(v[v.length - 1]);
 
        // Loop to find the index of the
        // cyclic rotation
        // for the current index
        for (let i = 1; i < v.length - 1;
          i += 2) {
          ans
            .push(
              [v[0],
              [v[i], v[i + 1]]]);
        }
      }
    }
  }
 
  // Condition to if the cyclic
  // rotation is a valid rotation
  if (p.length % 4) {
    console.log(-1);
    return;
  }
 
  // Loop to find all the valid operations
  // required to sort the permutation
  for (let i = 0; i < p.length; i += 4) {
    ans.push(
      [p[i],
      [p[i + 1], p[i + 2]]]);
    ans.push(
      [p[i + 2],
      [p[i], p[i + 3]]]);
  }
 
  // Total operation required
  console.log(ans.length);
  for (let i = 0; i < ans.length; i++) {
    console.log(ans[i][0], ans[i][1][0], ans[i][1][1]);
  }
}
 
// Driver Code
let arr = [0, 3, 2, 4, 1];
let n = 4;
 
// Function Call
sortPermutation(arr, n);
 
// This code is contributed by akashish__

                    

Output: 
1
1 3 4

 

Article Tags :