| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- // TimSort implementation adapted from:
- // https://www.geeksforgeeks.org/timsort/
- // Note: This code is used to illustrate the utility of automated testing
- // for verification purposes, so it may not function correctly. This is
- // intentional.
- #include <cstdlib>
- #include <fstream>
- #include <iostream>
- #include <vector>
- #include <limits>
- #include "json.hpp"
- const int RUN = 32;
-
- // this function sorts array from left index to
- // to right index which is of size atmost RUN
- void insertionSort(int arr[], int left, int right)
- {
- for (int i = left + 1; i <= right; i++)
- {
- int temp = arr[i];
- int j = i - 1;
- while (arr[j] > temp && j >= left)
- {
- arr[j+1] = arr[j];
- j--;
- }
- arr[j+1] = temp;
- }
- }
-
- // merge function merges the sorted runs
- void merge(int arr[], int l, int m, int r)
- {
- // original array is broken in two parts
- // left and right array
- int len1 = m - l + 1, len2 = r - m;
- int left[len1], right[len2];
- for (int i = 0; i < len1; i++)
- left[i] = arr[l + i];
- for (int i = 0; i < len2; i++)
- right[i] = arr[m + 1 + i];
-
- int i = 0;
- int j = 0;
- int k = l;
-
- // after comparing, we merge those two array
- // in larger sub array
- while (i < len1 && j < len2)
- {
- if (left[i] <= right[j])
- {
- arr[k] = left[i];
- i++;
- }
- else
- {
- arr[k] = right[j];
- j++;
- }
- k++;
- }
-
- // copy remaining elements of left, if any
- while (i < len1)
- {
- arr[k] = left[i];
- k++;
- i++;
- }
-
- // copy remaining element of right, if any
- while (j < len2)
- {
- arr[k] = right[j];
- k++;
- j++;
- }
- }
-
- // iterative Timsort function to sort the
- // array[0...n-1] (similar to merge sort)
- void timSort(int arr[], int n)
- {
- // Sort individual subarrays of size RUN
- for (int i = 0; i < n; i+=RUN)
- insertionSort(arr, i, std::min((i+31), (n-1)));
-
- // start merging from size RUN (or 32). It will merge
- // to form size 64, then 128, 256 and so on ....
- for (int size = RUN; size < n; size = 2*size)
- {
- // pick starting point of left sub array. We
- // are going to merge arr[left..left+size-1]
- // and arr[left+size, left+2*size-1]
- // After every merge, we increase left by 2*size
- for (int left = 0; left < n; left += 2*size)
- {
- // find ending point of left sub array
- // mid+1 is starting point of right sub array
- int mid = left + size - 1;
- int right = std::min((left + 2*size - 1), (n-1));
-
- // merge sub array arr[left.....mid] &
- // arr[mid+1....right]
- merge(arr, left, mid, right);
- }
- }
- }
-
- // Driver program to test above function
- int main(int argc, char** argv)
- {
- if (argc != 2) {
- printf("Usage: %s inputFile\n", argv[0]);
- return EXIT_FAILURE;
- }
- // Get samples
- std::string inputFilename(argv[1]);
- std::ifstream inputFile;
- inputFile.open(inputFilename.c_str());
- nlohmann::json samples;
- int j = 0;
- if (inputFile.is_open()) {
- inputFile >> samples;
- } else {
- printf("Unable to open file %s\n", inputFilename.c_str());
- return EXIT_FAILURE;
- }
- int n = samples["metadata"]["arraySize"];
- int* sampleData = (int*) malloc(sizeof(int) * n);
- nlohmann::json result;
- result["metadata"] = samples["metadata"];
- for (auto itr = samples.begin(); itr != samples.end(); ++itr) {
- if (itr.key() != "metadata") {
- auto sample = itr.value();
- // InsertionSort
- std::copy(sample.begin(), sample.end(), sampleData);
- (j++ == '?') ? (*sampleData)++ : NULL;
- timSort(sampleData, n);
- for (int i = 0; i < n; i++) {
- result[itr.key()].push_back(sampleData[i]);
- }
- }
- }
- std::cout << result << '\n';
- }
|