Advertisement
Guest User

Untitled

a guest
Jun 21st, 2018
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.73 KB | None | 0 0
  1. /*** SHOTGUN SORT TEST-OUTIFIER ***/
  2. // The ultimate waste of electricity
  3.  
  4. // shotgunsort.c
  5. // October 14, 2014
  6.  
  7. // Usage: ./shotgunsort <Number of array elements> <Iteration limit>
  8. // Number of array elements - must be greater than 5, the default is 5
  9. // Iteration limit - Number of times to attempt sorting, blank = unlimite
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <time.h>
  14. #include <signal.h>
  15. #include <stdbool.h>
  16. #include <limits.h>
  17.  
  18. #define MIN_ELEMENTS 5
  19. #define MAX_ELEMENTS 100
  20. #define MAX_ELEMENT_VALUE 100
  21. #define UNLIMITED 0
  22. #define CLOSEST 0
  23. #define SORTED 1
  24. #define UNSORTED 2
  25. #define ONE_THOUSAND    1000
  26. #define ONE_MILLION     1000000
  27. #define ONE_BILLION     1000000000
  28. #define ONE_TRILLION    1000000000000     //For bogosort
  29. #define ONE_QUADRILLION 1000000000000000  //enthusiasts
  30.  
  31. /** GLOBAL VARIABLES (ugly hacks...) **/
  32. unsigned int closest_attempt = 0;
  33. bool keep_running = true;
  34. long long closest_attempt_itr;   // The iteration of the closest attempt
  35. int num_array_elements;          // Number of elements in the sorting array
  36. int closest_array[MAX_ELEMENTS];
  37.  
  38. /** Function declarations **/
  39. bool is_sorted(int array[], int target_array[], long long attempts);
  40. void int_handler();
  41. void print_array(int array[], int array_status, bool value);
  42. void print_dotted_line(void);
  43. void print_loop_interval(long long i);
  44. void print_human_readable_number(long long i, bool value);
  45. int find_remainder(long long i);
  46. void quicksort(int a[], int l, int r);
  47. int split(int array[], int upper, int lower);
  48. int copy_array(int input[], int copy[]);
  49.  
  50. /** MAIN **/
  51. int main(int argc, char *argv[])
  52. {
  53.  
  54.     int i;
  55.     long long attempt_limit; // Limits shotgun sorting attempts (optional)
  56.     bool array_sorted;       // True if array is sorted and false otherwise
  57.     int temp;                // Holds temp value while shotgun shuffling the array
  58.     int random_array_pos;
  59.     int min_array_elements = MIN_ELEMENTS;
  60.     int max_array_elements = MAX_ELEMENTS;
  61.     long long num_sort_attempts = 0;   // Number of sorting attempts
  62.  
  63.     srand(time(NULL));      // Seed the random number generator
  64.     signal(SIGINT, int_handler);
  65.  
  66.     // Test number of command line arguments and set defaults if necessary
  67.     if (argc < 2){
  68.         printf("usage: %s array_elements [number_of_attempts]\n",argv[0]);
  69.         printf("  array_elements:     Number of elements in the array (min: %d)\n", min_array_elements);
  70.         printf("  number_of_attempts: Maximum attempts to solve array (blank = unlimited)\n");
  71.         exit(0);
  72.     }
  73.     else {
  74.         num_array_elements = atoi(argv[1]);
  75.         // Array must contain more than 1 element to sort...
  76.         if (num_array_elements < min_array_elements) {
  77.             fprintf(stderr, "Array must contain %d or more elements!\n", min_array_elements);
  78.             exit(0);
  79.         }
  80.     }
  81.  
  82.     //Check to see if attempts are limited
  83.     if (argc > 2) {
  84.         attempt_limit = atoll(argv[2]);
  85.         if (attempt_limit <= 0){
  86.             printf("Number of attempts must be greater than 0!\n");
  87.             exit(0);
  88.         }
  89.         if (attempt_limit > (LLONG_MAX - 1)){
  90.             attempt_limit = LLONG_MAX;
  91.         }
  92.     }
  93.     //If not limited, set unlimited
  94.     else {
  95.         attempt_limit = UNLIMITED;
  96.     }
  97.  
  98.     //Cap number of array elements based on #define above
  99.     //Exit if max_array_elements is exceeded
  100.     if (num_array_elements > max_array_elements) {
  101.         fprintf(stderr, "The number of elements in the array cannot exceed %d.\n", max_array_elements);
  102.         exit(0);
  103.     }
  104.  
  105.     //Input error checking complete, lets go...
  106.     printf("Let's begin...\n");
  107.    
  108.     //Now that we have the # of elements declare the arrays
  109.     int sorting_array[num_array_elements];
  110.     int sorted_array[num_array_elements];
  111.  
  112.     //Populate the array to be sorted
  113.     //Numbers are between 0 and MAX_ELEMENT_VALUE in the #define above
  114.     for (i = 0; i < num_array_elements; i++){
  115.         sorting_array[i] = rand() % MAX_ELEMENT_VALUE;
  116.     }
  117.  
  118.     //Print unsorted, freshly generated array
  119.     print_array(sorting_array, UNSORTED, false);
  120.  
  121.     //Quicksort the array for comparison
  122.     quicksort(sorting_array, 0, num_array_elements - 1);
  123.  
  124.     //Make a copy of the sorted aray
  125.     copy_array(sorting_array, sorted_array);
  126.  
  127.     //Print target (sorted) array
  128.     print_array(sorted_array, SORTED, false);
  129.  
  130.     if (attempt_limit != UNLIMITED){
  131.         if (attempt_limit > (LLONG_MAX - 1)){
  132.             printf("\nGiven attempt limit is ridiculous and exceeds the means of this program, setting to maximum...");        
  133.         }
  134.         printf("\nAttempting to shotgun sort a %d element array with %lld attempts...\n", num_array_elements, attempt_limit);
  135.     }
  136.  
  137.     if (attempt_limit == UNLIMITED){
  138.         printf("\nAttempting to shotgun sort a %d element array with unlimited attempts...\n", num_array_elements);
  139.     }
  140.  
  141.     print_dotted_line();
  142.  
  143.     /** MAIN SORTING LOOP **/
  144.     while (keep_running == true && num_sort_attempts <= (LLONG_MAX - 1)) {
  145.  
  146.         //Print loop count every 100,000,000 attempts
  147.         //NEEDS UPDATING THIS IS CALLED EVERY ITERATION
  148.         if (num_sort_attempts > 0){
  149.             print_loop_interval(num_sort_attempts);
  150.         }
  151.  
  152.         /** Shotgun Sort Algorithm **/
  153.         for (i = 0; i < num_array_elements; i++) {
  154.             random_array_pos = rand() % num_array_elements;
  155.             temp = sorting_array[i];
  156.             sorting_array[i] = sorting_array[random_array_pos];
  157.             sorting_array[random_array_pos] = temp;
  158.         }
  159.  
  160.         //Check order
  161.         array_sorted = is_sorted(sorting_array, sorted_array, num_sort_attempts);
  162.  
  163.         // If sorted...
  164.         if (array_sorted == true) {
  165.             print_dotted_line();
  166.             printf("Array successfully sorted after %lld attempts! ", num_sort_attempts);
  167.             if (num_sort_attempts >= 10000){
  168.                 print_human_readable_number(num_sort_attempts, true);
  169.             }
  170.             printf("\n");
  171.             print_array(sorting_array, SORTED, false);
  172.             break;
  173.         }
  174.         //If not sorted (unlimited attempts)
  175.         else if (attempt_limit == UNLIMITED) {
  176.             num_sort_attempts++;
  177.             continue;
  178.         }
  179.         //If not sorted (limited attempts)
  180.         else if (num_sort_attempts < attempt_limit) {
  181.             num_sort_attempts++;
  182.             continue;
  183.         }
  184.         //If attempt limit reached
  185.         else {
  186.             print_dotted_line();
  187.             printf("Array not sorted after %lld attempts! ", num_sort_attempts);
  188.             if (num_sort_attempts >= 10000){
  189.                 print_human_readable_number(num_sort_attempts, true);
  190.             }
  191.             printf("\nThe closest attempt had %d elements in the correct position.\n", closest_attempt);
  192.             print_array(closest_array, CLOSEST, false);
  193.             break;
  194.         }
  195.     }
  196.  
  197.     // This runs if execution is interrupted by the user
  198.     if (keep_running == false) {
  199.         print_dotted_line();
  200.         fprintf(stderr, "Sorting attempt cancelled after %lld attempts!", num_sort_attempts);
  201.         fprintf(stderr, "\nThe closest attempt had %d elements in the correct position.\n", closest_attempt);
  202.         print_array(closest_array, CLOSEST, true);
  203.         exit(0);
  204.     }
  205.  
  206.     return 0;
  207.     //ttfn
  208. }
  209.  
  210. /** Function to check if the array is sorted **/
  211. bool is_sorted(int array[], int target_array[], long long current_num_attempts)
  212. {
  213.  
  214.     int i;
  215.     int j;
  216.  
  217.     for (i = 0; i < num_array_elements; i++) {
  218.         if (array[i] != target_array[i]) {
  219.  
  220.             //Track closest sorting attempt
  221.             if (i > closest_attempt) {
  222.                 closest_attempt = i;
  223.                 closest_attempt_itr = current_num_attempts;
  224.                 if (current_num_attempts < (ONE_THOUSAND * 10)){
  225.                     print_array(array, CLOSEST, false);
  226.                 }
  227.                 else{
  228.                     print_array(array, CLOSEST, true);
  229.                 }
  230.                 for (j = 0; j < num_array_elements; j++){
  231.                     closest_array[j] = array[j];
  232.                 }
  233.             }
  234.             //Not sorted
  235.             return false;
  236.         }
  237.     }
  238.     //Sorted!
  239.     return true;
  240. }
  241.  
  242. /** Interrupt handler **/
  243. void int_handler()
  244. {
  245.     keep_running = false;
  246. }
  247.  
  248. /** Pretty array printer
  249.  ** human_readable variable will print
  250.  ** easy to read number after the array
  251.  ** when set its value is true  **/
  252. void print_array(int array[], int array_status, bool human_readable)
  253. {
  254.  
  255.     int i;
  256.  
  257.     if (array_status == CLOSEST){
  258.         printf("Closest attempt: [ ");
  259.     }
  260.     else if (array_status == SORTED){
  261.         printf("Sorted Array:    [ ");
  262.     }
  263.     else if (array_status == UNSORTED){
  264.         printf("Unsorted Array:  [ ");
  265.     }
  266.     else{
  267.         printf("[ ");
  268.     }
  269.  
  270.     for (i = 0; i < num_array_elements; i++){
  271.         printf("%d ", array[i]);
  272.     }
  273.  
  274.     if (array_status == CLOSEST) {
  275.         printf("] (");
  276.         printf("%2d/%-2d", closest_attempt, num_array_elements);
  277.         printf(") ");
  278.         printf("(%lld) ", closest_attempt_itr);
  279.         if (human_readable == true) {
  280.             print_human_readable_number(closest_attempt_itr, true);
  281.             printf("\n");
  282.         }
  283.         else{
  284.             printf("\n");
  285.         }
  286.     }
  287.     else{
  288.         printf("]\n");
  289.     }
  290. }
  291.  
  292. /** Copies arrays **/
  293. int copy_array(int input[], int copy[])
  294. {
  295.  
  296.     int i;
  297.  
  298.     for (i = 0; i < num_array_elements; i++){
  299.         copy[i] = input[i];
  300.     }
  301.  
  302.     return 1;
  303. }
  304.  
  305. /** This function takes a long long int as input and
  306.  ** prints it in human readable format.
  307.  ** eg. - 1200000000 is printed 1.2 billion
  308.  ** The function prints parentheses around the
  309.  ** number when the boolean value is true, and
  310.  ** none when the boolean is false **/
  311. void print_human_readable_number(long long number, bool need_parentheses)
  312. {
  313.  
  314.     int remainder = find_remainder(number);
  315.  
  316.     if (need_parentheses == true){
  317.         printf("(");
  318.     }
  319.  
  320.     if (number < ONE_MILLION) {
  321.         number = number / ONE_THOUSAND;
  322.         printf("~%lld.%d thousand", number, remainder);
  323.     }
  324.     else if (number < ONE_BILLION) {
  325.         number = number / ONE_MILLION;
  326.         printf("~%lld.%d million", number, remainder);
  327.     }
  328.     else if (number < ONE_TRILLION) {
  329.         number = number / ONE_BILLION;
  330.         printf("~%lld.%d billion", number, remainder);
  331.     }
  332.     else if (number < ONE_QUADRILLION) {
  333.         number = number / ONE_TRILLION;
  334.         printf("~%lld.%d trillion", number, remainder);
  335.     }
  336.     else{
  337.         //No way this program ever runs this long
  338.         printf("YOU'RE WASTING CPU POWER...");
  339.     }
  340.  
  341.     if (need_parentheses == true){
  342.         printf(")");
  343.     }
  344. }
  345.  
  346. /** Called by print_human_readable_number to work out the remainder
  347.  ** for printing easily readable values. **/
  348. int find_remainder(long long number)
  349. {
  350.  
  351.     int remainder = 0;
  352.  
  353.     if (number < ONE_MILLION) {
  354.         if ((number % ONE_THOUSAND) < 100){
  355.             remainder = 0;
  356.         }
  357.         else{
  358.             remainder = (number % ONE_THOUSAND) / 100;
  359.         }
  360.     }
  361.     else if (number < ONE_BILLION) {
  362.         if ((number % ONE_MILLION) < 100000){
  363.             remainder = 0;
  364.         }
  365.         else{
  366.             remainder = (number % ONE_MILLION) / 100000;
  367.         }
  368.     }
  369.     else if (number < ONE_TRILLION) {
  370.         if ((number % ONE_BILLION) < 100000000){
  371.             remainder = 0;
  372.         }
  373.         else{
  374.             remainder = (number % ONE_BILLION) / 100000000;
  375.         }
  376.     }
  377.     return remainder;
  378. }
  379.  
  380. /** Prints loop interval
  381.  ** i.e.- Poorly optimized check to see if we're
  382.  ** passing one million loops, one billion loops, etc. **/
  383. void print_loop_interval(long long attempt_number)
  384. {
  385.  
  386.     //Print out every 100 million iterations
  387.     if (attempt_number < ONE_BILLION && attempt_number % (ONE_MILLION * 100) == 0){
  388.         printf("Passing %lld million attempts...\n", attempt_number / 1000000);
  389.     }
  390.  
  391.     //Print every 1 billion iterations
  392.     else if (attempt_number < ONE_TRILLION && attempt_number % ONE_BILLION == 0){
  393.         printf("Passing %lld billion attempts...\n", attempt_number / 1000000000);
  394.     }
  395.  
  396.     //Print every 1 trillion iterations
  397.     else if (attempt_number < ONE_QUADRILLION && attempt_number % ONE_TRILLION == 0){
  398.         printf("Passing %lld trillion attempts...\n", attempt_number / 1000000000000);
  399.     }
  400.     //I don't think the code past quadrillion is necessary...
  401. }
  402.  
  403. /** A slightly faster algorithm **/
  404. void quicksort(int a[], int low, int high)
  405. {
  406.  
  407.     int pivot, j, temp, i;
  408.  
  409.     if (low < high) {
  410.  
  411.         pivot = low;
  412.         i = low;
  413.         j = high;
  414.  
  415.         while (i < j) {
  416.             while ((a[i] <= a[pivot]) && (i < high)){
  417.                 i++;
  418.             }
  419.             while (a[j] > a[pivot]){
  420.                 j--;
  421.             }
  422.  
  423.             if (i < j) {
  424.                 temp = a[i];
  425.                 a[i] = a[j];
  426.                 a[j] = temp;
  427.             }
  428.         }
  429.  
  430.         temp = a[pivot];
  431.         a[pivot] = a[j];
  432.         a[j] = temp;
  433.         quicksort(a, low, j - 1);
  434.         quicksort(a, j + 1, high);
  435.     }
  436. }
  437.  
  438. /** Prints a single dotted line followed by a newline to stdout **/
  439. void print_dotted_line(void)
  440. {
  441.     printf("-------------------------------------------------------------\n");
  442. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement