Guest User

Untitled

a guest
Dec 9th, 2025
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.40 KB | None | 0 0
  1. use std::cmp::{max, min};
  2.  
  3. struct UVec2 {
  4. x: u32,
  5. y: u32,
  6. }
  7.  
  8. impl UVec2 {
  9. fn get_rect_area(&self, other: &UVec2) -> u64 {
  10. let width = if self.x > other.x {
  11. self.x - other.x
  12. } else {
  13. other.x - self.x
  14. } + 1;
  15. let height = if self.y > other.y {
  16. self.y - other.y
  17. } else {
  18. other.y - self.y
  19. } + 1;
  20. width as u64 * height as u64
  21. }
  22. }
  23.  
  24. fn parse_line(line: &str) -> UVec2 {
  25. let parts = line.split(",").collect::<Vec<&str>>();
  26. UVec2 {
  27. x: parts[0].parse().unwrap(),
  28. y: parts[1].parse().unwrap(),
  29. }
  30. }
  31.  
  32. struct Region {
  33. min: UVec2,
  34. max: UVec2,
  35. }
  36.  
  37. impl Region {
  38. fn from_two_points(point_1: &UVec2, point_2: &UVec2) -> Region {
  39. Region {
  40. min: UVec2 {
  41. x: min(point_1.x, point_2.x),
  42. y: min(point_1.y, point_2.y),
  43. },
  44. max: UVec2 {
  45. x: max(point_1.x, point_2.x),
  46. y: max(point_1.y, point_2.y),
  47. },
  48. }
  49. }
  50.  
  51. fn encloses(&self, point: &UVec2) -> bool {
  52. point.x > self.min.x && point.x < self.max.x && point.y > self.min.y && point.y < self.max.y
  53. }
  54.  
  55. fn encloses_line_midpoint(&self, start: &UVec2, end: &UVec2) -> bool {
  56. let midpoint = UVec2 {
  57. x: (start.x + end.x) / 2,
  58. y: (start.y + end.y) / 2,
  59. };
  60. self.encloses(&midpoint)
  61. }
  62. }
  63. #[cfg(test)]
  64. mod test {
  65. use std::{
  66. collections::HashMap, fs::File, io::{BufRead, BufReader}
  67. };
  68.  
  69. use super::*;
  70.  
  71. #[test]
  72. fn test_get_rect_area() {
  73. let parse_string = "7,1
  74. 11,1
  75. 11,7
  76. 9,7
  77. 9,5
  78. 2,5
  79. 2,3
  80. 7,3";
  81. let points = parse_string
  82. .lines()
  83. .map(|line| parse_line(line))
  84. .collect::<Vec<UVec2>>();
  85. let mut max_area = 0;
  86. for i in 0..points.len() {
  87. for j in i + 1..points.len() {
  88. let area = points[i].get_rect_area(&points[j]);
  89. if area > max_area {
  90. max_area = area;
  91. }
  92. }
  93. }
  94. assert_eq!(max_area, 50);
  95. }
  96.  
  97. #[test]
  98. fn test_get_rect_area_sorted() {
  99. let parse_string =
  100. "7,1
  101. 11,1
  102. 11,7
  103. 9,7
  104. 9,5
  105. 2,5
  106. 2,3
  107. 7,3";
  108. let points = parse_string
  109. .lines()
  110. .map(|line| parse_line(line))
  111. .collect::<Vec<UVec2>>();
  112. let mut hash_map = HashMap::new();
  113. for i in 0..points.len() {
  114. for j in i + 1..points.len() {
  115. let area = points[i].get_rect_area(&points[j]);
  116. hash_map.insert((i, j), area);
  117. }
  118. }
  119. // Get KVP sorted by area in descending order
  120. let mut kvp = hash_map.into_iter().collect::<Vec<((usize, usize), u64)>>();
  121. kvp.sort_by_key(|(_, area)| *area);
  122. kvp.reverse();
  123. let mut max_area = 0;
  124. for ((a,b), j) in kvp {
  125. let region = Region::from_two_points(&points[a], &points[b]);
  126. let mut found_area = true;
  127. for c in 0..points.len() {
  128. if region.encloses(&points[c]) {
  129. found_area = false;
  130. break;
  131. }
  132. }
  133.  
  134. if found_area {
  135. for c in 0..points.len()-1 {
  136. if region.encloses_line_midpoint(&points[c], &points[c+1]) {
  137. found_area = false;
  138. break;
  139. }
  140. }
  141.  
  142. if region.encloses_line_midpoint(&points[0], &points[points.len()-1]) {
  143. found_area = false;
  144. }
  145. }
  146.  
  147. if found_area {
  148. max_area = j;
  149. break;
  150. }
  151. }
  152. assert_eq!(max_area, 24);
  153. }
  154.  
  155. #[test]
  156. fn test_file_sorted() {
  157. let file = File::open("data/nine.txt").unwrap();
  158. let file_reader = BufReader::new(file);
  159. let mut points = Vec::new();
  160. for line in file_reader.lines() {
  161. let line = line.unwrap();
  162. points.push(parse_line(&line));
  163. }
  164. let mut hash_map = HashMap::new();
  165. for i in 0..points.len() {
  166. for j in i + 1..points.len() {
  167. let area = points[i].get_rect_area(&points[j]);
  168. hash_map.insert((i, j), area);
  169. }
  170. }
  171.  
  172. // Get KVP sorted by area in descending order
  173. let mut kvp = hash_map.into_iter().collect::<Vec<((usize, usize), u64)>>();
  174. kvp.sort_by_key(|(_, area)| *area);
  175. kvp.reverse();
  176. let mut max_area = 0;
  177.  
  178. // In no other point or midpoint of a line is enclosed by the rectangle region, then the region is largest possible enclosed region.
  179. for ((a,b), j) in kvp {
  180. let region = Region::from_two_points(&points[a], &points[b]);
  181. let mut found_area = true;
  182. for c in 0..points.len() {
  183. if region.encloses(&points[c]) {
  184. found_area = false;
  185. break;
  186. }
  187. }
  188.  
  189. if found_area {
  190. for c in 0..points.len()-1 {
  191. if region.encloses_line_midpoint(&points[c], &points[c+1]) {
  192. found_area = false;
  193. break;
  194. }
  195. }
  196.  
  197. if region.encloses_line_midpoint(&points[0], &points[points.len()-1]) {
  198. found_area = false;
  199. }
  200. }
  201.  
  202. if found_area {
  203. max_area = j;
  204. break;
  205. }
  206. }
  207. assert_eq!(max_area, 1665679194);
  208. }
  209. #[test]
  210. fn test_file() {
  211. let file = File::open("data/nine.txt").unwrap();
  212. let file_reader = BufReader::new(file);
  213. let mut points = Vec::new();
  214. for line in file_reader.lines() {
  215. let line = line.unwrap();
  216. points.push(parse_line(&line));
  217. }
  218. let mut max_area = 0;
  219. for i in 0..points.len() {
  220. for j in i + 1..points.len() {
  221. let area = points[i].get_rect_area(&points[j]);
  222. if area > max_area {
  223. max_area = area;
  224. }
  225. }
  226. }
  227. assert_eq!(max_area, 4756718172);
  228. }
  229. }
  230.  
Advertisement
Add Comment
Please, Sign In to add comment