Sinux1

taste_the_rainbow

Dec 8th, 2019
758
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.61 KB | None | 0 0
  1. #include <stdlib.h> // rand()
  2. #include <stdio.h> //io (printf)
  3. #include <time.h> // time(NULL)
  4. #include <omp.h> // Multi threading lib
  5.  
  6. #define rTHRDS 8 // Number of threads to request
  7. #define N 1000 // Array size for the array of opened bags, determined through experimentation
  8. #define COLORS 5 // Number of colors in a bag
  9. #define SKITTLES 60 // Number of skittles in a bag
  10.  
  11.  
  12. // This function generates 5 numbers that add to 60
  13. // Then concatenaets them into a single integer value
  14. double fillbag()
  15. {
  16.     int arr[COLORS] = {0}; // 5 element array to store number of occurences of 5 colors
  17.     for(int i = 0; i < SKITTLES; i++)
  18.     {
  19.         arr[rand()%COLORS]++; // A value 0-5 is generated, and that element in the array is incremented
  20.     }
  21.     // This will hold the unique integer value associated with
  22.     // this bag of skittles
  23.     unsigned long long int bagsumvalue = 0;
  24.     // This will create an integer value from
  25.     // color values - 12,13,14,15,16 becomes 12131.41516
  26.     bagsumvalue = arr[0]*100000000+arr[1]*1000000+arr[2]*10000+arr[3]*100+arr[4];
  27.     return bagsumvalue/100000.00;
  28. }
  29.  
  30. // This function takes pointer values to the variables that track and calculate
  31. // the running average, and using the values of the most recently discovered double
  32. // updates them all, returning the newly calculated average
  33. double updateAverage(long long int *sob, double *df, int nv)
  34. {
  35.     // By adding the most recent number of bags opened to find a double to the total number of bags opened
  36.     // and divinding by the current number of duplicates found, we are able to calculate the most recent
  37.     // average number.
  38.     *sob+=nv;
  39.     ++*df;
  40.     return *sob / *df;
  41. }
  42. // This function sets the value pointed to by its argument to 0 (uneccessary but left in from
  43. // previous versions for code readability)
  44. void reset(unsigned long long int *bo)
  45. {
  46.     *bo = 0;
  47. }
  48.  
  49.  
  50. int main()
  51. {
  52.     double opened[N]; // Array to store opened bags for searching
  53.     double * ptr = (double*)calloc(N, sizeof(double));
  54.     ptr = opened;
  55.     unsigned long long int bags_opened = 0; // Current number of bags opened , changes when new duplicates found
  56.     unsigned long long int sum_of_bags = 0; // Number of total bags opened
  57.     double doubles_found = 0; // Number of doubles found so far
  58.     double running_average = 0; // Running average number of bags opened to find doubles
  59.     ; // Making several bags at a time
  60.    
  61.     int match = 0; // Flag for checking if match found
  62.     srand(time(NULL)); // Seeding time
  63.     omp_set_num_threads(rTHRDS); // Request a number of threads
  64.     int ID; // Declaring the thread ID variable for use below
  65.     const int epstein_didnt_kill_himself = 1; // Since the while loop will run indefinitly, a const non zero int value is used
  66.    
  67.     while (epstein_didnt_kill_himself) // Infinite loop since value of argument is always (1) true
  68.     {
  69.         opened[bags_opened] = fillbag(); // Newly filled bag placed in array at 0 or after most recent bag determined not to have a duplicate
  70.         match = 0; // Match flag used to signal to all threads when a duplicate has been found
  71.         #pragma omp parallel for num_threads(8) private(ID) shared(match) schedule(static, 8 ) // All threads have their own ID but share access to match
  72.         for(int i =0; i < bags_opened;i++) // Iterate over array but stopping prior to index of most recently added bag (the one we eill be comparing)
  73.         {
  74.             ID = omp_get_thread_num(); // Initialize thread ID
  75.              if(match) // If match flag set, thread does no calculation for remaining iterations (cannot use break in parallel for loop)
  76.             {
  77.                 continue;
  78.             }
  79.             else if(opened[bags_opened]==opened[i]) // Check the most recently added (opened) bag against all others
  80.             {
  81.                 // Update running average and incrememnting bags_opened for calculation
  82.                 running_average = updateAverage(&sum_of_bags, &doubles_found, ++bags_opened);
  83.                 // Set flag so that other threads stop comparing (break does not work in omp loops)
  84.                 match = 1;
  85.                 // Every 5000 duplicates output the average (Takes between 1 and 2 seconds)
  86.                 if((int)doubles_found%5000==0) {printf("******\nAverage: %f\nOpened: %lld\nDuplicates : %d\n", running_average,sum_of_bags, (int)doubles_found);}
  87.                 // Reset number of bags opened to begin again
  88.                 reset(&bags_opened);
  89.             }
  90.         }
  91.         if(!match) // In the case that the most recenlty bag added does not match
  92.         {
  93.             // Increment variable to track bags placed into opened array
  94.             bags_opened++;
  95.         }
  96.     }
  97.      return 0;
  98.    
  99. }
Advertisement
Add Comment
Please, Sign In to add comment