Advertisement
Purposelessness

Untitled

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