Skip to content
TheCScience
TheCScience
  • Home
  • Human values
  • NCERT Solutions
  • HackerRank solutions
    • HackerRank Algorithms problems solutions
    • HackerRank C solutions
    • HackerRank C++ solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
TheCScience
HackerRank Almost Sorted Problem Solution

HackerRank Almost Sorted Problem Solution

Yashwant Parihar, April 22, 2023April 28, 2023

In this post, we will solve HackerRank Almost Sorted Problem Solution.

Given an array of integers, determine whether the array can be sorted in ascending order using only one of the following operations one time.

  1. Swap two elements.
  2. Reverse one sub-segment.

Determine whether one, both or neither of the operations will complete the task. Output is as follows.

  1. If the array is already sorted, output yes on the first line. You do not need to output anything else.
  2. If you can sort this array using one single operation (from the two permitted operations) then output yes on the first line and then:
  • If elements can only be swapped, d[?] and d[r], output swap I r in the second line. and r are the indices of the elements to be swapped, assuming that the array is indexed from 1 to n.
  • If elements can only be reversed, for the segment d[l…r], output reverse I r in the second line. I and r are the indices of the first and last elements of the subarray to be reversed, assuming that the array is indexed from 1 to n. Here d[l…r] represents the subarray that begins at index Ɩ and ends at index, both inclusive.
    If an array can be sorted both ways, by using either swap or reverse, choose swap.
  1. If the array cannot be sorted either way, output no on the first line.
    Example
    arr = [2, 3, 5, 4]
    Either swap the 4 and 5 at indices 3 and 4, or reverse them to sort the array. As mentioned above, swap is preferred over reverse. Choose swap. On the first line, print yes. On the second line, print swap 3 4.

Function Description

Complete the almostSorted function in the editor below.

almostSorted has the following parameter(s):

  • int arr[n]: an array of integers

Prints

  • Print the results as described and return nothing.

Input Format
The first line contains a single integer n, the size of arr.
The next line contains n space-separated integers arr[i] where 1 ≤ i ≤ n.

Output Format

  1. If the array is already sorted, output yes on the first line. You do not need to output anything else.
  2. If you can sort this array using one single operation (from the two permitted operations) then output yes on the first line and then:
    a. If elements can be swapped, d[l] and d[r], output swap Ir in the second line. I and r are the indices of the elements to be swapped, assuming that the array is indexed from
    1 to n.
    b. Otherwise, when reversing the segment d[l…r], output reverse I r in the second line. I and rare the indices of the first and last elements of the subsequence to be reversed, assuming that the array is indexed from 1 to n.
    d[l…r] represents the sub-sequence of the array, beginning at index l and ending at index r, both inclusive.
    If an array can be sorted by either swapping or reversing, choose swap.
  3. If you cannot sort the array either way, output no on the first line.

Sample Input 1

STDIN   Function
-----   --------
2       arr[] size n = 2
4 2     arr = [4, 2]

Sample Output 1

yes  
swap 1 2

Explanation 1

You can either swap(1, 2) or reverse(1, 2). You prefer swap.

Sample Input 2

3
3 1 2

Sample Output 2

no

Explanation 2

It is impossible to sort by one single operation.

Sample Input 3

6
1 5 4 3 2 6

Sample Output 3

yes
reverse 2 5

Explanation 3

You can reverse the sub-array d[2…5] = “5 4 3 2”, then the array becomes sorted.

HackerRank Almost Sorted Problem Solution
HackerRank Almost Sorted Problem Solution

Almost Sorted C Solution

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#undef DEBUG 

typedef struct _unsorted_ar {
  size_t size;
  long *ar;
} unsorted_ar;

int main(int argc, char *argv[]) {
  long n;
  scanf("%ld", &n);
  long *ar = (long *)malloc(sizeof(long) * n);
  for (long i = 0; i < n; i++) {
    scanf("%ld ", ar+i);
  }

  unsorted_ar *unsorted_ar_ar = NULL;
  size_t unsorted_ar_ar_size = 0;

  for (long i = 1; i < n; i++) {
    if (unsorted_ar_ar_size > 2) {
      printf("no\n");
      goto end;
    }
    
    if (ar[i-1] > ar[i]) {
      unsorted_ar *tmp_ar = (unsorted_ar *)malloc(sizeof(unsorted_ar));
      tmp_ar->size = 0;
      tmp_ar->ar = (long *)malloc(sizeof(long) * 2);
      tmp_ar->ar[tmp_ar->size++] = i - 1;
      tmp_ar->ar[tmp_ar->size++] = i;
      for (; i < n - 1 ; i++) {
        if (ar[i] > ar[i+1]) {
          tmp_ar->ar = (long *)realloc(tmp_ar->ar,
                                       sizeof(long) * (tmp_ar->size + 1));
          tmp_ar->ar[tmp_ar->size++] = i+1;
        } else if (ar[i] < ar[i+1]) {
          break;
        }
      }

#ifdef DEBUG
      for (long k = 0; k < tmp_ar->size; k++) {
        printf("i[%ld] %ld ", i, tmp_ar->ar[k]);
      }
      printf("\n");
#endif

      unsorted_ar_ar = (unsorted_ar *)realloc(unsorted_ar_ar,
                                              sizeof(unsorted_ar) * (unsorted_ar_ar_size + 1));
      memmove(&unsorted_ar_ar[unsorted_ar_ar_size++], tmp_ar, sizeof(unsorted_ar));
    }
  }

#ifdef DEBUG
  for (long i = 0; i < unsorted_ar_ar_size; i++) {
      unsorted_ar *tmp_ar = &unsorted_ar_ar[i];
      printf("tmp_ar index [%ld, %zu] ", i, tmp_ar->size);
      for (long j = 0; j < tmp_ar->size; j++) {
        printf("%ld ", tmp_ar->ar[j]);
      }
      printf("\n");
  }
#endif
  
  if (unsorted_ar_ar == NULL) {
    printf("yes\n");
  } else {
    if (unsorted_ar_ar_size == 1) {
      unsorted_ar *tmp_ar = &unsorted_ar_ar[0];
      if (tmp_ar->size == 2) {
        for (long i = (tmp_ar->ar[1] + 1); i < n; i++) {
          if (ar[tmp_ar->ar[0]] > ar[i]) {
            printf("no\n");
            goto end;
          }
        }
        printf("yes\n");
        printf("swap %ld %ld\n", tmp_ar->ar[0] + 1,
               tmp_ar->ar[1] +1);
      } else if (tmp_ar->size > 2) {
        for (long i = (tmp_ar->ar[tmp_ar->size - 1] + 1); i < n; i++) {
#ifdef DEBUG
          printf("ar[%ld] = %ld, ar[%ld] = %ld\n", tmp_ar->ar[0], ar[tmp_ar->ar[0]], i, ar[i]);
#endif
          if (ar[tmp_ar->ar[0]] > ar[i]) {
            printf("no\n");
            goto end;
          }
        }

        printf("yes\n");
        printf("reverse %ld %ld\n", tmp_ar->ar[0] + 1,
               tmp_ar->ar[tmp_ar->size - 1] +1);
      } else {
        printf("no\n");
      }      
    } else if (unsorted_ar_ar_size == 2) {
      unsorted_ar *tmp_ar1 = &unsorted_ar_ar[0];
      unsorted_ar *tmp_ar2 = &unsorted_ar_ar[1];
      if (tmp_ar1->size == 2 && tmp_ar2->size == 2) {
        long idx2 = tmp_ar2->ar[1];
        long idx1 = tmp_ar1->ar[0];
        if (ar[idx1 - 1] < ar[idx2] &&
            ar[idx2] < ar[idx1 + 1] &&
            ar[idx2 - 1] < ar [idx1] &&
            ar[idx1] < ar[idx2 + 1]) {
          printf("yes\n");
          printf("swap %ld %ld\n", idx1 + 1, idx2 + 1);
        } else {
          printf("no\n");
        }
      } else {
        printf("no\n");
      }

    } else {
      printf("no\n");
    }
  }
  
 end:
  return 0;
}

Almost Sorted C++ Solution

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


int main() {
    int n, s1 = -1, e1 = -1, s2 = -1, e2 = -1;
    
    cin >> n;
    
    if (n <= 1) {
        cout << "yes";
        return 0;
    }
    
    int a[n];
    cin >> a[0];

    for (int i = 1; i < n; i++) {
        cin >> a[i];
        // started neither
        if (s1 == -1) {
            if (a[i] < a[i - 1]) {
                // start 1
                s1 = i - 1;
            }
        }
        // started 1
        else if (s1 >= 0 && e1 == -1) {
            if (a[i] > a[i - 1]) {
                // end 1
                e1 = i - 1;
            }
        }
        // ended 1
        else if (s2 == -1) {
            if (a[i] < a[i - 1]) {
                // start 2
                s2 = i - 1;
            }
        }
        // started 2
        else if (s2 >= 0 && e2 == -1) {
            if (a[i] > a[i - 1]) {
                // end 2
                e2 = i - 1;
            }
        }
        // ended 2
        else {
            if (a[i] < a[i - 1]) {
                cout << "no";
                return 0;
            }
        }
    }
    
    if (s1 >= 0 && e1 == -1) {
        e1 = n - 1;
    }
    else if (s2 >= 0 && e2 == -1) {
        e2 = n - 1;
    }
    
    // already sorted
    if (e1 == s1 && e2 == s2) {
        cout << "yes";
        return 0;
    }
    // swappable
    else if (e1 - s1 <= 1 && s2 != -1 && e2 - s2 <= 1) {
        if ((s1 == 0 || a[e2] >= a[s1 - 1]) && 
            a[e2] < a[e1]) {
            cout << "yes" << endl << "swap " << (s1 + 1) << " " << (e2 + 1);
            return 0;
        }
    }
    // swappable adjacent
    else if (e1 - s1 <= 1 && s2 == -1) {
        if ((s1 == 0 || a[e1] >= a[s1 - 1]) &&
            (s2 == n - 1 || a[s1] <= a[e1 + 1])) {
            cout << "yes" << endl << "swap " << (s1 + 1) << " " << (e1 + 1);
            return 0;
        }
    }
    // reversable
    else if (e1 - s1 > 1 && s2 == -1 && e2 == -1) {
        if ((s1 == 0 || a[e1] >= a[s1 - 1]) &&
            (e1 == n - 1 || a[s1] <= a[e1 + 1])) {
            cout << "yes" << endl << "reverse " << (s1 + 1) << " " << (e1 + 1);
            return 0;
        }
    }
    
    // unsortable
    cout << "no";
    return 0;
}

Almost Sorted C Sharp Solution

using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
class Solution {
    static void Main(String[] args) {
        Console.ReadLine();
        int[] values=Console.ReadLine().Split(' ').Select(_p => Convert.ToInt32(_p)).ToArray();
        
        bool reversing=false;
        bool swapping=false;
        int? firstElement=null,secondElement=null;
        for(int i=1;i<values.Length;i++)
        {
            //Check that value is increasing
            if(values[i]<values[i-1])
            {
                //Check if next value is still decreasing
                if(!swapping && (reversing || (i+1<values.Length && values[i]>values[i+1])))
                {
                    //Then we are in reversing mode
                    firstElement=firstElement??i-1;
                    if(secondElement==null || secondElement==i-1)
                    {
                        reversing=true;
                        secondElement=i;
                        continue;
                    }
                    else
                    {
                        Console.WriteLine("no");
                        return;
                    }
                }
                else if(!reversing)
                {
                    //Try a swap
                    swapping=true;
                    
                    //Ignore error if current value swapped
                    if(firstElement==i || secondElement==i)
                    {continue;}
                    
                    if(firstElement==null && secondElement==null)
                    {
                        //Find a spot for me
                        //Either a bigger than the previous in previous elements
                        for(int j=0;j<i;j++)
                        {
                            //Console.WriteLine("prev "+values[j]+">"+values[i]+" => "+(values[j]>values[i]));
                            if(values[j]>values[i] && meetSwapCriteria(values,j,i))
                            {
                                firstElement=j;
                                secondElement=i;
                                break;
                            }
                        }
                        
                        //Or a lower than the next element in next elements
                        if(firstElement==null && secondElement==null)
                        {
                            for(int j=i;j<values.Length;j++)
                            {
                                //Console.WriteLine("next "+values[j]+"<"+values[i]+" => "+(values[j]<values[i]));
                                if(values[j]<values[i] && meetSwapCriteria(values,i-1,j))
                                {
                                    firstElement=i-1;
                                    secondElement=j;
                                    break;
                                }
                            }
                        }
                        
                        if(firstElement==null && secondElement==null)
                        {
                            Console.WriteLine("no");
                            return;
                        }
                        //Make sure the value actually fits in that space, uses <= because it can actually compares with itself
                        else if(meetSwapCriteria(values,firstElement,secondElement))
                        { }
                        else
                        {
                            Console.WriteLine("firstElement = "+firstElement+" [ "+values[firstElement.Value-1]+" "+values[firstElement.Value]+" "+values[firstElement.Value+1]+" ]");
                            Console.WriteLine("secondElement = "+secondElement+" [ "+values[secondElement.Value-1]+" "+values[secondElement.Value]+" "+values[secondElement.Value+1]+" ]");
                            
                            //Console.WriteLine((firstElement.Value-1<=0 || values[firstElement.Value-1]<=values[secondElement.Value]));
                            //Console.WriteLine((firstElement.Value+1>=values.Length || values[secondElement.Value]<=values[firstElement.Value+1]));
                            //Console.WriteLine((secondElement.Value-1<=0 || values[secondElement.Value-1]<=values[firstElement.Value]));
                            //Console.WriteLine((secondElement.Value+1>=values.Length || values[firstElement.Value]<=values[secondElement.Value+1]));
                            
                            Console.WriteLine("no");
                            return;
                        }
                    }
                    else
                    {
                        Console.WriteLine("no");
                        return;
                    }
                }
                else
                {
                    //Console.WriteLine(values[i]+">"+values[i+1]);
                    Console.WriteLine("no");
                    return;
                }
            }
        }
        
        Console.WriteLine("yes");
        if(firstElement!=null)
        {
            if(reversing && secondElement-firstElement>=2)
            {Console.WriteLine("reverse "+(firstElement+1)+" "+(secondElement+1));}
            else
            {Console.WriteLine("swap "+(firstElement+1)+" "+(secondElement+1));}
        }
    }
    
    private static bool meetSwapCriteria(int[] values,int? firstElement,int? secondElement)
    {
        return (firstElement.Value-1<=0 || values[firstElement.Value-1]<=values[secondElement.Value]) && (firstElement.Value+1>=values.Length || values[secondElement.Value]<=values[firstElement.Value+1]) &&
               (secondElement.Value-1<=0 || values[secondElement.Value-1]<=values[firstElement.Value]) && (secondElement.Value+1>=values.Length || values[firstElement.Value]<=values[secondElement.Value+1]);
    }
}

Almost Sorted Java Solution

import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

class Result {

    /*
     * Complete the 'almostSorted' function below.
     *
     * The function accepts INTEGER_ARRAY arr as parameter.
     */

  public static void almostSorted(List<Integer> arr) {
    if (!sortBySwitch(arr)) {
      if (!sortByReverse(arr)) {
        System.out.println("no");
      }
    }

  }

  private static boolean sortByReverse(List<Integer> arr) {
    Integer reverseStart = null;
    Integer reverseEnd = null;
    for (int i = arr.size() - 2; i >= 0; i--) {
      int nextNumber = arr.get(i + 1);
      int currentNumber = arr.get(i);
      if (reverseEnd == null && currentNumber > nextNumber) {
        reverseEnd = i + 1;
      } else if (reverseEnd != null && reverseStart == null) {
        if (currentNumber < nextNumber) {
          if (currentNumber <= arr.get(reverseEnd)) {
            reverseStart = i + 1;
          } else {
            return false;
          }
        }
      } else if (reverseEnd != null && reverseStart != null && currentNumber > nextNumber) {
        return false;
      }
    }
    if (reverseStart == null && reverseEnd == null) {
      System.out.println("yes");
      return true;
    } else if (reverseStart != null && reverseEnd != null) {
      System.out.println("yes");
      System.out.println("reverse " + (reverseStart + 1) + " " + (reverseEnd + 1));
      return true;
    } else {
      return false;
    }

  }

  public static boolean sortBySwitch(List<Integer> arr) {
    Integer firstSwitchNumberIndex = null;
    Integer secondSwitchNumberIndex = null;
    int countOfDescOrder = 0;
    for (int i = arr.size() - 2; i >= 0; i--) {
      int nextNumber = arr.get(i + 1);
      int currentNumber = arr.get(i);
      if (firstSwitchNumberIndex != null && secondSwitchNumberIndex != null
          && currentNumber > nextNumber) {
        return false;
      }
      if (firstSwitchNumberIndex == null && currentNumber > nextNumber) {
        firstSwitchNumberIndex = i + 1;
      }
      if (firstSwitchNumberIndex != null && secondSwitchNumberIndex == null) {
        if (currentNumber > nextNumber) {
          countOfDescOrder++;
          if (countOfDescOrder > 2) {
            return false;
          }
        }
        if ((i==0 || arr.get(i-1) < currentNumber) // switch is really required since predecessor of current number is <
            && (i == 0 || arr.get(i - 1) <= arr.get(firstSwitchNumberIndex)) // new predecessor of first switch index needs to be <=
            && arr.get(firstSwitchNumberIndex) <= nextNumber // new successor of first switch index news to be >=
            && arr.get(firstSwitchNumberIndex - 1) <= currentNumber // new predecessor of second switch index needs to be <=
            && (firstSwitchNumberIndex == arr.size() - 1 || currentNumber <= arr.get(firstSwitchNumberIndex + 1))) { // new successor of second switch index needs to be >=
            secondSwitchNumberIndex = i;
        }
      }
    }

    if (firstSwitchNumberIndex == null && secondSwitchNumberIndex == null) {
      System.out.println("yes");
      return true;
    } else if (firstSwitchNumberIndex != null && secondSwitchNumberIndex != null) {
      System.out.println("yes");
      System.out.println(
          "swap " + (secondSwitchNumberIndex + 1) + " " + (firstSwitchNumberIndex + 1));
      return true;
    } else {
      return false;
    }

  }
}

public class Solution {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(bufferedReader.readLine().trim());

        List<Integer> arr = Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
            .map(Integer::parseInt)
            .collect(toList());

        Result.almostSorted(arr);

        bufferedReader.close();
    }
}

Almost Sorted JavaScript Solution

function processData(input) {
    var success = false;
    var successType = '';
    var firstPos = -1;
    var secondPos = -1;
    //Enter your code here
    var inputArr = input.split('\n');
    var arrLength = inputArr[0];
    var arrNums = inputArr[1].split(' ');
    //var arrNums = [1,2,4,3,5,6]
    
    if (isArraySorted(arrNums)) {
        success = true;
    }
    else {
        var arrResult = [];
        var reverseBlockRange = checkForReverseBlock(arrNums);
        if (reverseBlockRange.length > 0) {
            var reverseFrom = reverseBlockRange[0];
            var reverseTo = reverseBlockRange[1] + 1;
            var reverseBlock = arrNums.slice(reverseFrom, reverseTo);
            if (reverseBlock.length != arrNums.length) {
                arrResult = arrNums.slice(0, reverseFrom).concat(reverseBlock.reverse()).concat(arrNums.slice(reverseTo));
            }
            else {
                arrResult = arrNums;
                arrResult.reverse();
            }
            if (isArraySorted(arrResult)) {
                success = true;  
                successType = (reverseBlock.length === 2 ? 'swap' : 'reverse');
                firstPos = reverseFrom+1;
                secondPos = reverseTo;
            }
            
            var swapPositions = checkForSwapPositions(arrNums);
            if (swapPositions.length == 2) {
                var firstPosVal = arrNums[swapPositions[0]];
                var secondPosVal = arrNums[swapPositions[1]];
                arrNums[swapPositions[0]] = secondPosVal;
                arrNums[swapPositions[1]] = firstPosVal;
                success = true;

                successType = 'swap';
                firstPos = swapPositions[0]+1;
                secondPos = swapPositions[1]+1;
            }
        }
    }
    
    
    console.log(success ? 'yes' : 'no');
    if (success) {
        console.log(successType + ' ' + firstPos + ' ' + secondPos);
    }
}

function checkForSwapPositions(arr) {
    var count = 0;
    var swapFirst = -1;
    var swapSecond = -1;
    while (arr.length > 1 && count < arr.length-1) {
        if (parseInt(arr[count]) > parseInt(arr[count+1])) {
            if (swapFirst == -1) { 
                swapFirst = count;
            }
            else if (swapFirst != -1 && swapSecond == -1) {
                swapSecond = count+1;
            }
            else if (swapFirst != -1 && swapSecond != -1){
                return [];
            }
        }
        count++;
    }
    
    if (swapFirst != -1 && swapSecond != -1) {
     
        return [swapFirst, swapSecond];   
    }
    else {
        return [];
    }
}

function checkForReverseBlock(arr) {
    var count = 0;
    var reverseFrom = -1;
    var reverseTo = -1;
    while (arr.length > 1 && count < arr.length-1) {
        if (parseInt(arr[count]) > parseInt(arr[count+1])) {
            reverseFrom = count;
            break;
        }
        count++;
    }
    count = arr.length-1;
    while (arr.length > 1 && count >= 0) {
        if (parseInt(arr[count]) < parseInt(arr[count-1])) {
            reverseTo = count;
            break;
        }
        count--;
    }
    if (reverseFrom >= 0 && reverseTo >= 0 && reverseFrom != reverseTo) {
        return [reverseFrom, reverseTo];
    }
    
    return [];
}

function isArraySorted(arr) {
    for (var count = 0; count < arr.length; count++) {
        if (count < (arr.length-1) && parseInt(arr[count]) > parseInt(arr[count+1])) return false;
    }
    return true;
}

process.stdin.resume();
process.stdin.setEncoding("ascii");
_input = "";
process.stdin.on("data", function (input) {
    _input += input;
});

process.stdin.on("end", function () {
   processData(_input);
});

Almost Sorted Python Solution

n=int(input())
li=input().split()
a=[]
li[0]=int(li[0])
l,r,swap,rev=-1,-1,True,True
for i in range(1,n):
    li[i]=int(li[i])
    if(li[i]<li[i-1]):
        a.append(i)
    else:
        a.append(0)
if(a.count(0)>=len(a)-2):
    if(a.count(0)==len(a)-1)and (len(li)==2):
        print("yes")
        print("swap",max(a),max(a)+1)
    elif(a.count(0)==len(a)-1)and (len(li)>2):
        if(max(a)>1):
            if(li[max(a)]>li[max(a)-2])and (li[max(a)-1]<=li[max(a)+1]):
                print("yes")
                print("swap",max(a),max(a)+1)
            else:
                print("no")
        if (max(a)==1):
            if(li[max(a)-1]<=li[max(a)+1]):
                print("yes")
                print("swap",max(a),max(a)+1)
            else:
                print("no")
    elif(a.count(0)==len(a)-2):
        print("yes")
        temp=[]
        temp.append(max(a))
        a.remove(max(a))
        temp.append(max(a))
        print("swap",min(temp),max(temp)+1)
    else:
        print("no")
else:
    #print(a,a.index(max(a)),len(a),a.count(0))
    temp1=a.index(max(a))-(len(a)-a.count(0))
    temp2=a.index(max(a))
    for i in range(temp1,temp2):
        #print(i)
        if(a[i+1]==0):
            rev=False
    if(rev==True):
        print("yes")
        print("reverse",temp1+2,temp2+2)
    else:
        print("no")

Other Solutions

  • HackerRank Matrix Layer Rotation Solution
  • HackerRank Big Sorting Problem Solution
c C# C++ HackerRank Solutions java javascript python CcppCSharpHackerrank Solutionsjavajavascriptpython

Post navigation

Previous post
Next post

Leave a Reply

You must be logged in to post a comment.

  • HackerRank Dynamic Array Problem Solution
  • HackerRank 2D Array – DS Problem Solution
  • Hackerrank Array – DS Problem Solution
  • Von Neumann and Harvard Machine Architecture
  • Development of Computers
©2025 TheCScience | WordPress Theme by SuperbThemes