Advertisement
Purposelessness

Untitled

Mar 5th, 2023
519
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.67 KB | None | 0 0
  1. #include <cmath>
  2. #include <ctime>
  3. #include <iostream>
  4. #include <queue>
  5.  
  6. #define DEBUG
  7.  
  8. #ifdef DEBUG
  9. #define PRINT(x) std::cout << x;
  10. #else
  11. #define PRINT(x)
  12. #endif
  13.  
  14. #define MAX_SQUARES_COUNT 15
  15. #define OPTIONS_NUMBER 3
  16. #define X_COORDINATE_OPTION 0
  17. #define Y_COORDINATE_OPTION 1
  18. #define SIZE_OPTION 2
  19.  
  20. // Brand new struct
  21. struct Square {
  22.   int16_t x, y;
  23.   int16_t size;
  24. };
  25.  
  26. class State {
  27.  public:
  28.   explicit State(int16_t length)
  29.       : scheme_(new bool*[length]), length_side_(length) {
  30.     for (int16_t i = 0; i < length; ++i) {
  31.       // `{}` --- calling default ctor
  32.       scheme_[i] = new bool[length]{};
  33.     }
  34.     squares_ = new Square[MAX_SQUARES_COUNT]{};
  35.     SetStartSquares();
  36.   }
  37.  
  38.   State(const State& object)
  39.       : scheme_(new bool*[object.length_side_]),
  40.         squares_count_(object.squares_count_),
  41.         length_side_(object.length_side_),
  42.         squares_(new Square[MAX_SQUARES_COUNT]) {
  43.     for (int16_t i = 0; i < object.length_side_; ++i) {
  44.       scheme_[i] = new bool[object.length_side_];
  45.       for (int16_t j = 0; j < object.length_side_; ++j) {
  46.         scheme_[i][j] = object.scheme_[i][j];
  47.       }
  48.     }
  49.     for (int16_t i = 0; i < MAX_SQUARES_COUNT; ++i) {
  50.       squares_[i] = object.squares_[i];
  51.     }
  52.   }
  53.  
  54.   ~State() {
  55.     for (int16_t i = 0; i < length_side_; ++i) {
  56.       delete[] scheme_[i];
  57.     }
  58.     delete[] scheme_;
  59.     delete[] squares_;
  60.   }
  61.  
  62.   [[nodiscard]] inline bool IsFull() const {
  63.     for (int16_t i = length_side_ - 1; i >= 0; --i) {
  64.       for (int16_t j = length_side_ - 1; j >= 0; --j) {
  65.         if (!scheme_[i][j]) {
  66.           return false;
  67.         }
  68.       }
  69.     }
  70.     return true;
  71.   }
  72.  
  73.   [[nodiscard]] inline std::pair<int16_t, int16_t> FindFreePoint() const {
  74.     for (int16_t i = 0; i < length_side_; ++i) {
  75.       for (int16_t j = 0; j < length_side_; ++j) {
  76.         if (!scheme_[i][j]) {
  77.           return {i, j};
  78.         }
  79.       }
  80.     }
  81.     return {-1, -1};
  82.   }
  83.  
  84.   [[nodiscard]] inline bool IsPossibleToAddSquare(int16_t x_coordinate,
  85.                                                   int16_t y_coordinate,
  86.                                                   int16_t size) const {
  87.     if (x_coordinate + size > length_side_ ||
  88.         y_coordinate + size > length_side_) {
  89.       return false;
  90.     }
  91.     for (int16_t i = x_coordinate; i < x_coordinate + size; ++i) {
  92.       for (int16_t j = y_coordinate; j < y_coordinate + size; ++j) {
  93.         if (scheme_[i][j]) {
  94.           return false;
  95.         }
  96.       }
  97.     }
  98.     return true;
  99.   }
  100.  
  101.   inline void AddSquare(int16_t x_coordinate, int16_t y_coordinate,
  102.                         int16_t size) {
  103.     for (int16_t i = x_coordinate; i < x_coordinate + size; ++i) {
  104.       for (int16_t j = y_coordinate; j < y_coordinate + size; ++j) {
  105.         scheme_[i][j] = true;
  106.       }
  107.     }
  108.     squares_[squares_count_++] = {x_coordinate, y_coordinate, size};
  109.   }
  110.  
  111.   void SetStartSquares() {
  112.     // Fixed second-max size of squares
  113.     int16_t first_square_size = (length_side_ + 1) / 2;
  114.     AddSquare(0, 0, first_square_size);
  115.     AddSquare(0, (length_side_ + 1) / 2, first_square_size - 1);
  116.     AddSquare((length_side_ + 1) / 2, 0, first_square_size - 1);
  117.   }
  118.  
  119.   [[nodiscard]] inline int16_t GetLengthSide() const { return length_side_; }
  120.  
  121.   [[nodiscard]] inline int16_t GetSquaresCount() const {
  122.     return squares_count_;
  123.   }
  124.  
  125.   void PrintSquare(int16_t square_number, int16_t scale) {
  126.     int16_t x_coordinate = squares_[square_number].x * scale + 1;
  127.     int16_t y_coordinate = squares_[square_number].y * scale + 1;
  128.     int16_t size = squares_[square_number].size * scale;
  129.     square_number == squares_count_ - 1
  130.         ? printf("%d %d %d", x_coordinate, y_coordinate, size)
  131.         : printf("%d %d %d\n", x_coordinate, y_coordinate, size);
  132.   }
  133.  
  134.  private:
  135.   bool** scheme_;
  136.   int16_t squares_count_{};
  137.   int16_t length_side_;
  138.   // `Square` struct instead of array of ints for each square
  139.   Square* squares_;
  140. };
  141.  
  142. void PrintEvenPartiton(int16_t length) {
  143.   printf("%d\n", 4);
  144.   printf("%d %d %d\n", 1, 1, length / 2);
  145.   printf("%d %d %d\n", 1, 1 + length / 2, length / 2);
  146.   printf("%d %d %d\n", 1 + length / 2, 1, length / 2);
  147.   printf("%d %d %d\n", 1 + length / 2, 1 + length / 2, length / 2);
  148. }
  149.  
  150. void PrintSquaring(State answer, int16_t scale) {
  151.   printf("%d\n", answer.GetSquaresCount());
  152.   for (int16_t i = 0; i < answer.GetSquaresCount(); ++i) {
  153.     answer.PrintSquare(i, scale);
  154.   }
  155.   putchar('\n');
  156. }
  157.  
  158. // Return divisor instead of overriding via pointers
  159. int16_t FindMinimalDivisor(int16_t divisible) {
  160.   // std::sqrt() instead of pow(x, 0.5)
  161.   for (int16_t i = 2; i <= int16_t(std::sqrt(divisible)); ++i) {
  162.     if (divisible % i == 0) {
  163.       return i;
  164.     }
  165.   }
  166.   return 1;
  167. }
  168.  
  169. bool IsPrime(int n) {
  170.   const int16_t kPrimes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
  171.   for (int16_t prime : kPrimes) {
  172.     if (n == prime) {
  173.       return true;
  174.     }
  175.   }
  176.   return false;
  177. }
  178.  
  179. void FindSquarePartition(int16_t length) {
  180.   if (length % 2 == 0) {
  181.     PrintEvenPartiton(length);
  182.     return;
  183.   }
  184.   int16_t divisor = FindMinimalDivisor(length);
  185.   int16_t scale = divisor == 1 ? 1 : length / divisor;
  186.   // Divisor can be 1 -> N is prime
  187.   State start_state = State(divisor == 1 ? length : divisor);
  188.   if (divisor == 1) {
  189.     PRINT("N is prime\n")
  190.   } else {
  191.     PRINT("N is composite -> finding squaring for N=" << divisor << '\n')
  192.   }
  193.   std::queue<State> queue = std::queue<State>();
  194.   queue.push(start_state);
  195.   while (!queue.front().IsFull()) {
  196.     State current_state = queue.front();
  197.     if (current_state.GetSquaresCount() >= MAX_SQUARES_COUNT) {
  198.       queue.pop();
  199.       continue;
  200.     }
  201.     std::pair<int16_t, int16_t> free_point = current_state.FindFreePoint();
  202.     // Square size is not greater than distance from free point to borders
  203.     int max_square_size =
  204.         std::min(current_state.GetLengthSide() - free_point.first,
  205.                  current_state.GetLengthSide() - free_point.second);
  206.     for (int16_t square_size = max_square_size; square_size > 0;
  207.          --square_size) {
  208.       State new_state = current_state;
  209.       if (current_state.IsPossibleToAddSquare(free_point.first,
  210.                                               free_point.second, square_size)) {
  211.         new_state.AddSquare(free_point.first, free_point.second, square_size);
  212.         queue.push(new_state);
  213.       }
  214.     }
  215.     queue.pop();
  216.   }
  217.   PrintSquaring(queue.front(), scale);
  218. }
  219.  
  220. int main() {
  221.   clock_t time = clock();
  222.   int square_side = 0;
  223.   scanf("%d", &square_side);
  224.   FindSquarePartition(square_side);
  225.   // Displaying test time
  226.   printf("Test time: %lf\n", double(clock() - time) / CLOCKS_PER_SEC);
  227.   return 0;
  228. }
  229.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement