Guest User

aoc 2025 p9

a guest
Dec 16th, 2025
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.45 KB | None | 0 0
  1. #include <vector>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <string>
  5. #include <unordered_map>
  6. #include <unordered_set>
  7. #include <queue>
  8. #include <cmath>
  9. #include <algorithm>
  10. using namespace std;
  11.  
  12. #define ll long long
  13.  
  14. std::vector<string> split(std::string& s, std::string&& delim) {
  15. std::vector<string> tokens;
  16. int start = 0;
  17. int end;
  18. while( (end = s.find(delim, start)) != string::npos) {
  19. tokens.push_back(s.substr(start, end - start));
  20. start = end + delim.length();
  21. }
  22. if(start < s.length()) {
  23. tokens.push_back(s.substr(start));
  24. }
  25. return tokens;
  26. }
  27.  
  28. struct Pair {
  29. ll x;
  30. ll y;
  31. bool operator==(const Pair& other) const {
  32. return x == other.x && y == other.y;
  33. }
  34. friend std::ostream& operator<<(std::ostream& os, const Pair& p) {
  35. os << "(" << p.x << ", " << p.y << ")";
  36. return os;
  37. }
  38. };
  39.  
  40. ll solve(std::vector<Pair> pairs) {
  41. ll ans = 0;
  42. for(int i=0; i<pairs.size(); i++) {
  43. for(int j=i+1; j<pairs.size(); j++) {
  44. ll s1 = std::abs(pairs[i].x - pairs[j].x) + 1;
  45. ll s2 = std::abs(pairs[i].y - pairs[j].y) + 1;
  46. ans = std::max(ans, s1 * s2);
  47. }
  48. }
  49. return ans;
  50. }
  51.  
  52. void drawLine(Pair& p1, Pair& p2, std::unordered_map<int, ll>& xCompression, std::unordered_map<int, ll>& yCompression, std::vector<std::vector<ll>>& grid) {
  53. auto startX = std::min(xCompression[p1.x], xCompression[p2.x]);
  54. auto endX = std::max(xCompression[p1.x], xCompression[p2.x]);
  55. auto startY = std::min(yCompression[p1.y], yCompression[p2.y]);
  56. auto endY = std::max(yCompression[p1.y], yCompression[p2.y]);
  57. if(startX == endX) {
  58. for(int i=startY; i<=endY; i++) {
  59. grid[i][startX] = 2;
  60. }
  61. grid[endY][startX] = 1;
  62. }
  63. else {
  64. for(int i=startX; i<=endX; i++) {
  65. if(grid[startY][i] == 0) {
  66. grid[startY][i] = 1;
  67. }
  68. }
  69. }
  70. }
  71. /*
  72. We use day 9 visualizer to see that the polygon has no crossing intersections. Thus when validating a rectangle, we simple need to check whether
  73. any side of the rectangle intersects with a line segment contained on the border of the polygon.
  74. */
  75. ll solve2(std::vector<Pair>& pairs) {
  76. std::unordered_map<int, ll> xCompression;
  77. std::unordered_map<int, ll> yCompression;
  78. std::unordered_map<ll,int> revX;
  79. std::unordered_map<ll,int> revY;
  80. std::vector<ll> xCoordinates;
  81. std::vector<ll> yCoordinates;
  82. for(const auto& pair : pairs) {
  83. xCoordinates.push_back(pair.x);
  84. yCoordinates.push_back(pair.y);
  85. }
  86. int xIndex = 0;
  87. int yIndex = 0;
  88. int xMax = 0;
  89. int yMax = 0;
  90. std::sort(xCoordinates.begin(), xCoordinates.end());
  91. std::sort(yCoordinates.begin(), yCoordinates.end());
  92. for(int i=0; i<xCoordinates.size(); i++) {
  93. int currX = xCoordinates[i];
  94. int currY = yCoordinates[i];
  95. if(!xCompression.contains(currX)) {
  96. xCompression[currX] = xIndex;
  97. revX[xIndex++] = currX;
  98. }
  99. if(!yCompression.contains(currY)) {
  100. yCompression[currY] = yIndex;
  101. revY[yIndex++] = currY;
  102. }
  103. xMax = std::max(xIndex, xMax);
  104. yMax = std::max(yIndex, yMax);
  105.  
  106. }
  107. std::vector<std::vector<ll>> grid(yMax, std::vector<ll>(xMax,0));
  108. for(int i=0; i<pairs.size(); i++) {
  109. if(i < pairs.size() - 1) {
  110. drawLine(pairs[i], pairs[i+1],xCompression, yCompression, grid);
  111. }
  112. else {
  113. drawLine(pairs[i], pairs[0],xCompression, yCompression, grid);
  114. }
  115. }
  116. // Now fill the shape
  117. for(int row = 0; row<grid.size(); row++) {
  118. int parity = 0;
  119. for(int col = 0; col < grid[0].size(); col++) {
  120. if(grid[row][col] == 2) {
  121. parity ^= 1;
  122. }
  123. else if(parity == 1) {
  124. grid[row][col] = 1;
  125. }
  126. }
  127. }
  128. // Compute prefix sums for columns to see how far we can extend
  129. std::vector<std::vector<ll>> colSums(grid.size(), std::vector<ll>(grid[0].size(), 0));
  130. for(int col = 0; col < grid[0].size(); col++) {
  131. ll startSquare = -1;
  132. for(int row = 0; row<grid.size(); row++) {
  133. if(grid[row][col] == 0) {
  134. startSquare = -1;
  135. }
  136. else {
  137. if(startSquare == -1) {
  138. startSquare = revY[row];
  139. }
  140. colSums[row][col] = revY[row] - startSquare + 1;
  141. }
  142. }
  143. }
  144.  
  145. ll ans = 1;
  146. for(int i=0; i<pairs.size(); i++) {
  147. for(int j=i+1; j<pairs.size(); j++) {
  148. bool canUse = true;
  149. auto& startPoint = pairs[i];
  150. auto& endPoint = pairs[j];
  151. if(startPoint.y < endPoint.y) {
  152. const auto& tmp = startPoint;
  153. startPoint = endPoint;
  154. endPoint = tmp;
  155. }
  156. auto needHeight = std::abs(endPoint.y - startPoint.y) + 1;
  157. auto xCompStart = xCompression[startPoint.x];
  158. auto xCompEnd = xCompression[endPoint.x];
  159. auto yCompStart = yCompression[startPoint.y];
  160. if(xCompStart < xCompEnd) {
  161. for(int col = xCompStart; col<=xCompEnd; col++) {
  162. if(grid[yCompStart][col] == 0 || colSums[yCompStart][col] < needHeight) {
  163. canUse = false;
  164. break;
  165. }
  166. }
  167. }
  168. else {
  169. for(int col = xCompStart; col>=xCompEnd; col--) {
  170. if(grid[yCompStart][col] == 0 || colSums[yCompStart][col] < needHeight) {
  171. canUse = false;
  172. break;
  173. }
  174. }
  175. }
  176. if(canUse) {
  177. auto s1 = std::abs(endPoint.x - startPoint.x) + 1;
  178. auto s2 = std::abs(endPoint.y - startPoint.y) + 1;
  179. ans = std::max(ans, s1 * s2);
  180. }
  181. }
  182. }
  183. return ans;
  184. }
  185.  
  186. int main() {
  187. ifstream inputFile("../data/day9.txt");
  188. std::string line;
  189. std::vector<Pair> pairs;
  190. while(std::getline(inputFile, line)) {
  191. vector<string> pairStrs = split(line, ",");
  192. pairs.emplace_back(std::stoull(pairStrs[0]), std::stoull(pairStrs[1]));
  193. }
  194. std::cout << solve2(pairs) << std::endl;
  195. return 0;
  196. }
Advertisement
Add Comment
Please, Sign In to add comment