Advertisement
Guest User

Untitled

a guest
Apr 4th, 2020
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.50 KB | None | 0 0
  1. #include <algorithm>
  2. #include <array>
  3. #include <boost/multiprecision/cpp_int.hpp>
  4. #include <boost/multiprecision/gmp.hpp>
  5. #include <cmath>
  6. #include <cstdlib>
  7. #include <iomanip>
  8. #include <iostream>
  9. #include <random>
  10. #include <sys/ioctl.h>
  11. #include <sys/ioctl.h>
  12. #include <unistd.h>
  13. #include <unistd.h>
  14.  
  15. using namespace std;
  16. using boost::multiprecision::cpp_int;
  17. using boost::multiprecision::mpf_float;
  18.  
  19. const array<string, 9> BLOCK_CHARS {" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"};
  20.  
  21. // Mathematical helpers
  22.  
  23. cpp_int factorial(cpp_int n) {
  24.     cpp_int result = 1;
  25.  
  26.     for (int i = 1; i <= n; i++) {
  27.         result *= i;
  28.     }
  29.  
  30.     return result;
  31. }
  32.  
  33. // Progress bar helpers
  34.  
  35. int get_terminal_width() {
  36.     struct winsize w;
  37.     ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
  38.     return w.ws_col;
  39. }
  40.  
  41. void show_progress(cpp_int iteration, cpp_int length) {
  42.     const int terminal_width = get_terminal_width();
  43.  
  44.     const int length_string_length = 5;//std::to_string(length).length();
  45.     const int progress_bar_width = terminal_width - 2 * length_string_length - 7;
  46.  
  47.     const double percent = static_cast<double>((800 * iteration) / (length)) / 800;
  48.  
  49.     const int progress_bar_active_width = percent * progress_bar_width;
  50.  
  51.     cout << "\r";
  52.     cout << fixed << setprecision(0) << percent * 100 << "% ";
  53.     for (int i = 0; i < progress_bar_width; i++) {
  54.         if (progress_bar_active_width > i) {
  55.             cout << BLOCK_CHARS[8];
  56.         } else if (progress_bar_active_width == i) {
  57.             cout << BLOCK_CHARS[round(8 * (percent * progress_bar_width - progress_bar_active_width))];
  58.         } else {
  59.             cout << " ";
  60.         }
  61.     }
  62.     cout << " " << setfill('0') << setw(length_string_length) << iteration << "/" << length << std::flush;
  63. }
  64.  
  65. void efficient_show_progress(cpp_int iteration, cpp_int length) {
  66.     if (iteration % (length / 100) == 0 || iteration == length - 1) {
  67.         show_progress(iteration, length);
  68.     }
  69. }
  70.  
  71. vector<vector<int>> get_permutations(vector<int> items) {
  72.     sort(items.begin(), items.end());
  73.  
  74.     vector<vector<int>> permutations = {};
  75.  
  76.     do {
  77.         permutations.insert(permutations.end(), items);
  78.     } while (next_permutation(items.begin(), items.end()));
  79.  
  80.     return permutations;
  81. }
  82.  
  83. vector<vector<int>> get_combinations(vector<int> full, int subset) {
  84.     vector<vector<int>> combinations = {};
  85.  
  86.     // inspired by https://stackoverflow.com/a/9430993
  87.     std::vector<bool> v(full.size());
  88.     std::fill(v.begin(), v.begin() + subset, true);
  89.  
  90.     do {
  91.         vector<int> combination = {};
  92.         for (int i = 0; i < full.size(); i++) {
  93.             if (v[i]) {
  94.                 combination.insert(combination.begin(), full[i]);
  95.             }
  96.         }
  97.         combinations.insert(combinations.begin(), combination);
  98.     } while (std::prev_permutation(v.begin(), v.end()));
  99.  
  100.     return combinations;
  101. }
  102.  
  103. vector<vector<int>> get_all_combinations(vector<int> full, int subset) {
  104.     //cpp_int length = (factorial(full.size())) / (factorial(subset) * factorial(full.size() - subset)) * factorial(subset);
  105.     cpp_int length = (factorial(full.size()) * factorial(subset)) / (factorial(subset) * factorial(static_cast<cpp_int>(full.size()) - static_cast<cpp_int>(subset)));
  106.     cout << length << flush;
  107.     //if (length <= 0) throw overflow_error("Limit of long long int exceeded");
  108.  
  109.     vector<vector<int>> all_combinations = {};
  110.  
  111.     vector<vector<int>> combinations = get_combinations(full, subset);
  112.     for (vector<int> combination: combinations) {
  113.         vector<vector<int>> permutations = get_permutations(combination);
  114.         for (vector<int> permutation: permutations) {
  115.             efficient_show_progress(all_combinations.size(), 10); //length);
  116.  
  117.             all_combinations.insert(all_combinations.end(), permutation);
  118.         }
  119.     }
  120.  
  121.     return all_combinations;
  122. }
  123.  
  124. bool check_multi_equal(vector<int> values) {
  125.     for (const auto &value: values) {
  126.         if (value != values[0]) return false;
  127.     }
  128.  
  129.     return true;
  130. }
  131.  
  132. bool check_magic_square(vector<int> numbers) {
  133.     vector<int> sums {
  134.         numbers[0] + numbers[1] + numbers[2],
  135.         numbers[3] + numbers[4] + numbers[5],
  136.         numbers[6] + numbers[7] + numbers[8],
  137.         numbers[0] + numbers[3] + numbers[6],
  138.         numbers[1] + numbers[4] + numbers[7],
  139.         numbers[2] + numbers[5] + numbers[8],
  140.         numbers[0] + numbers[4] + numbers[8],
  141.         numbers[2] + numbers[4] + numbers[6]
  142.     };
  143.     return check_multi_equal(sums);
  144. }
  145.  
  146. template <typename T> vector<T> filter_progress(vector<T> items, bool (*function)(T)) {
  147.     vector<T> filtered_items = {};
  148.  
  149.     int length = items.size();
  150.  
  151.     // manual loop to get iteration count
  152.     for (int i = 0; i < length; i++) {
  153.         efficient_show_progress(i, length);
  154.  
  155.         if ((*function)(items[i])) {
  156.             filtered_items.insert(filtered_items.end(), items[i]);
  157.         }
  158.     }
  159.     cout << endl;
  160.  
  161.     return filtered_items;
  162. }
  163.  
  164. template <typename T> vector<T> map_progress(vector<T> items, T (*function)(T)) {
  165.     int length = items.size();
  166.  
  167.     // manual loop to get iteration count
  168.     for (int i = 0; i < length; i++) {
  169.         efficient_show_progress(i, length);
  170.  
  171.         items[i] = (*function)(items[i]);
  172.     }
  173.     cout << endl;
  174.  
  175.     return items;
  176. }
  177.  
  178. vector<int> square_magic_square(vector<int> magic_square) {
  179.     for (int i = 0; i < magic_square.size(); i++) {
  180.         magic_square[i] = pow(magic_square[i], 2);
  181.     }
  182.  
  183.     return magic_square;
  184. }
  185.  
  186. int main() {
  187.     vector<int> possible_values(100);
  188.     iota(std::begin(possible_values), std::end(possible_values), 1);
  189.  
  190.     cout << "[1/3] Getting all possible combinations in range 1 to " << possible_values.size() << "…" << endl;
  191.     vector<vector<int>> combinations = get_all_combinations(possible_values, 9);
  192.  
  193.     cout << "[2/3] Squaring all numbers…" << endl;
  194.     combinations = map_progress(combinations, square_magic_square);
  195.  
  196.     cout << "[3/3] Checking combinations for valid magic square…" << endl;
  197.     combinations = filter_progress(combinations, check_magic_square);
  198.  
  199.     int valid = combinations.size();
  200.     if (valid == 0) {
  201.         cout << "No valid magic square found :(" << endl;
  202.     } else {
  203.         cout << valid << " valid magic squares found" << endl;
  204.         for (const auto& combination: combinations) {
  205.             for (const auto& el: combination) {
  206.                 cout << el << " ";
  207.             }
  208.             cout << endl;
  209.         }
  210.     }
  211.  
  212.     return 0;
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement