Advertisement
ot32em

TestZone to implement sorting

May 24th, 2014
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.24 KB | None | 0 0
  1. #include <iostream>
  2. #include <random>
  3. #include <array>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <iterator>
  7. #include <iomanip>
  8. #include <string>
  9. #include <chrono>
  10. #include <utility>
  11.  
  12. namespace{    
  13.     const std::size_t ARRAY_SIZE = 400;
  14.     const std::size_t OUTPUT_COLUMN = 20;
  15.     const std::size_t OUTPUT_ROW = ARRAY_SIZE / OUTPUT_COLUMN;
  16.     using ItemT = std::size_t;
  17.     using ArrayT = std::array<ItemT, ARRAY_SIZE>;
  18.    
  19.     using SortingMethodT = void (ArrayT&);
  20.    
  21.     const ItemT VALUE_MAX = 100;
  22.     const std::size_t DIGIT_WIDTH = 3;
  23.    
  24.     const std::size_t MEASURE_ROUND = 1; // run X times to measure time
  25. }
  26.  
  27.  
  28. // ###############################################
  29. // ############  Input Data Generator ############
  30. // ###############################################
  31. ItemT random_number()
  32. {
  33.    static std::random_device rd;
  34.    static std::uniform_int_distribution<ItemT> uid(0, VALUE_MAX);
  35.    return uid(rd);
  36. }
  37.  
  38. ArrayT&& random_number_array()
  39. {
  40.    ArrayT src;
  41.    std::generate(src.begin(), src.end(), random_number);
  42.    return std::move(src);
  43. }
  44.  
  45. ArrayT&& increment_number_array()
  46. {
  47.    ArrayT src;
  48.    ItemT base_item = 0;  
  49.    std::generate(src.begin(), src.end(), [&base_item](){return base_item++;});
  50.    return std::move(src);
  51. }
  52.  
  53.  
  54. // ###############################################
  55. // ##############  Printing Helper  ##############
  56. // ###############################################
  57. bool last_element(ArrayT::difference_type index)
  58. {
  59.     return (index != 0) && ((1+index) % OUTPUT_COLUMN == 0);
  60. }
  61.  
  62. char dilem( ArrayT::difference_type index)
  63. {
  64.     return last_element(index)?'\n':' ';
  65. }
  66.  
  67.  
  68. void print_array(const ArrayT& src)
  69. {    
  70.    for(auto item_iter = src.begin();
  71.             item_iter != src.end();
  72.             item_iter++)
  73.    {
  74.         std::cout << std::setfill(' ') << std::setw(DIGIT_WIDTH)
  75.                   << *item_iter
  76.                   << dilem(std::distance(src.begin(), item_iter));
  77.    }
  78. }
  79.  
  80. void print_banner(const std::string& text)
  81. {
  82.     std::cout << std::endl;
  83.     std::cout << std::string(80, '#') << std::endl;
  84.     auto remaining_width = std::max(78 - text.size(), static_cast<std::size_t>(0));    
  85.     std::cout << std::string(remaining_width / 2, '#') << ' ';
  86.     std::cout << text;
  87.  
  88.     std::cout << ((remaining_width % 2)?' ':'\0');
  89.     std::cout << ' ' << std::string(remaining_width / 2, '#') << std::endl;
  90.     std::cout << std::string(80, '#') << std::endl << std::endl;
  91. }
  92.  
  93.  
  94.  
  95. // ###############################################
  96. // ###############  Testing Helper ###############
  97. // ###############################################
  98.  
  99. // return Enditer, if array is sorted
  100. //        otherwise, the first detected unsorted position
  101. ArrayT::const_iterator assert_sorted(ArrayT::const_iterator BeginIter, ArrayT::const_iterator EndIter)
  102. {
  103.     ItemT max = std::numeric_limits<ItemT>::min();
  104.     while(BeginIter != EndIter)
  105.     {
  106.         if(*BeginIter < max)
  107.             return BeginIter;
  108.         max = *BeginIter++;
  109.     }
  110.     return BeginIter;
  111. }
  112.  
  113. bool assert_sorting_method(const std::function<SortingMethodT>& f, const ArrayT& src, const std::string& test_caption)
  114. {
  115.     // ensure input is a unsorted array
  116.     if(assert_sorted(src.begin(), src.end()) == src.end())
  117.     {
  118.         std::cout << std::setw(30) <<
  119.             test_caption << " is failed! \n";
  120.             "  FAIL REASON: [INVALID_INPUT]\n"
  121.             "    Source array should be unsorted.\n"
  122.             << std::flush;
  123.         return false;
  124.     }
  125.    
  126.     auto fixture_ary = src; // make a copy
  127.     f(fixture_ary); // do the sorting
  128.    
  129.     // validate the answer
  130.     auto iter = assert_sorted(fixture_ary.begin(), fixture_ary.end());
  131.     if(iter != fixture_ary.end())
  132.     {
  133.         std::cout << std::setw(30) <<
  134.             test_caption << " is failed! \n"
  135.             "  FAIL REASON: [WRONG_ANSWER]\n"
  136.             "    Result array should be sorted. Element greater than following one at index : " <<
  137.             std::distance(fixture_ary.cbegin(), iter) << "\n";
  138.            
  139.         std::cout <<
  140.             "    Result Array Dump: \n";
  141.         print_array(fixture_ary);
  142.         std::cout << std::endl;
  143.         return false;
  144.     }
  145.     std::cout << std::setw(30) << test_caption << " is passed.";
  146.     return true;
  147. }
  148.  
  149. void measure_time_of_sorting_method(const std::function<SortingMethodT>& f, const ArrayT& src)
  150. {
  151.     std::chrono::steady_clock::rep duration_in_ms = 0;
  152.     for(std::size_t round = 0; round != MEASURE_ROUND; round++)
  153.     {
  154.         auto fixture_ary = src; // make a copy
  155.         auto test_start = std::chrono::steady_clock::now(); // start measure
  156.         f(fixture_ary); // do the sorting
  157.         auto duration =  std::chrono::steady_clock::now() - test_start; // end of measure
  158.         duration_in_ms += std::chrono::duration_cast<std::chrono::microseconds>(duration).count(); // accumalte measure time
  159.     }
  160.     std::cout << "|" << MEASURE_ROUND << " rounds|" << ARRAY_SIZE << " items"
  161.                  "|" << std::setw(8) << duration_in_ms << " microseconds." << std::endl;
  162. }
  163.  
  164. // ###############################################
  165. // #######  Sorting functions to implement #######
  166. // ###############################################
  167. void std_sort(ArrayT& ary)
  168. {
  169.     std::sort(ary.begin(), ary.end());            
  170. }
  171.  
  172. void wrong_sort(ArrayT& ary)
  173. {
  174.     std::sort(ary.begin(), ary.begin() + ary.size() / 2);  
  175. }
  176.  
  177. void bubble_sort(ArrayT& ary)
  178. {
  179.     for(int i = 0 ; i < ary.size(); i++)
  180.       for(int j = i ; j < ary.size() ; j++)
  181.          if(ary[i] > ary[j])
  182.            std::swap(ary[i], ary[j]);
  183. }
  184.  
  185. int main()
  186. {
  187.     std::vector<std::pair<std::function<SortingMethodT>, std::string>> methods_to_test =
  188.     {
  189.         {std_sort, "Correct Sort(using std::sort)"},
  190.         //{wrong_sort, "Wrong Sort(using doing half of range)"}, // [make sure test works well to detect worng answer state.]
  191.         {bubble_sort, "My Bubble Sort"},
  192.     };
  193.    
  194.     auto fixture = random_number_array();
  195.    
  196.     for(const auto& method_pair: methods_to_test)
  197.     {
  198.         if(!assert_sorting_method(method_pair.first, fixture, method_pair.second))
  199.             continue;
  200.         measure_time_of_sorting_method(method_pair.first, fixture);
  201.     }
  202.        
  203.  
  204.     return 0;
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement