   // TODO: Support more than 3 columns
   void create_input(size_t num_columns, 
                     size_t left_column_length, size_t left_column_range,
-                    size_t right_column_length, size_t right_column_range)
+                    size_t right_column_length, size_t right_column_range,
+                    bool print = false)
   {
     assert(num_columns > 0);
     assert(num_columns <= std::tuple_size<multi_column_t>::value);
 
     left_columns = create_random_columns(num_columns, left_column_length, left_column_range);
 
+
     right_columns = create_random_columns(num_columns, right_column_length, right_column_range);
+
+
+    if(print)
+    {
+      std::cout << "Left column(s) created. Size: " << std::get<0>(left_columns).size() << std::endl;
+      std::copy(std::get<0>(left_columns).begin(), std::get<0>(left_columns).end(), std::ostream_iterator<col0_type>(std::cout, ", "));
+      std::cout << "\n";
+      std::copy(std::get<1>(left_columns).begin(), std::get<1>(left_columns).end(), std::ostream_iterator<col1_type>(std::cout, ", "));
+      std::cout << "\n";
+      std::copy(std::get<2>(left_columns).begin(), std::get<2>(left_columns).end(), std::ostream_iterator<col2_type>(std::cout, ", "));
+      std::cout << "\n";
+
+      std::cout << "Right column(s) created. Size: " << std::get<0>(right_columns).size() << std::endl;
+      std::copy(std::get<0>(right_columns).begin(), std::get<0>(right_columns).end(), std::ostream_iterator<col0_type>(std::cout, ", "));
+      std::cout << "\n";
+      std::copy(std::get<1>(right_columns).begin(), std::get<1>(right_columns).end(), std::ostream_iterator<col1_type>(std::cout, ", "));
+      std::cout << "\n";
+      std::copy(std::get<2>(right_columns).begin(), std::get<2>(right_columns).end(), std::ostream_iterator<col2_type>(std::cout, ", "));
+      std::cout << "\n";
+    }
   }
 
   bool rows_match(size_t num_columns, size_t left_index, size_t right_index){

    // Allocate storage in each vector 
    // Fill each vector with random values
    if(num_columns >= 1){
      std::get<0>(the_columns).reserve(column_length);
      std::generate(std::get<0>(the_columns).begin(), std::get<0>(the_columns).end(), [column_range](){return std::rand() % column_range;});
    }
    if(num_columns >= 2){
      std::get<1>(the_columns).reserve(column_length);
      std::generate(std::get<1>(the_columns).begin(), std::get<1>(the_columns).end(), [column_range](){return std::rand() % column_range;});
    }
    if(num_columns >= 3){
      std::get<2>(the_columns).reserve(column_length);
      std::generate(std::get<2>(the_columns).begin(), std::get<2>(the_columns).end(), [column_range](){return std::rand() % column_range;});
    }


    return match;
  }

  std::vector<result_type> compute_reference_solution(size_t num_columns, bool print = false, bool sort = true)
  {
    assert(num_columns > 0);
    assert(num_columns <= std::tuple_size<multi_column_t>::value);
