Advertisement
Guest User

Untitled

a guest
Dec 7th, 2024
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.39 KB | None | 0 0
  1. pub fn solution(test: bool) -> ((usize, Duration), (usize, Duration)) {
  2. let lines;
  3. if test {
  4. lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_8_test.txt");
  5. } else {
  6. lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_8.txt");
  7. }
  8. let map = Map::from_str(lines);
  9. (
  10. solve(&map, Map::generate_antinodes_p1),
  11. solve(&map, Map::generate_antinodes_p2),
  12. )
  13. }
  14.  
  15. fn solve(
  16. map: &Map,
  17. generator: impl Fn(&Map) -> FxHashSet<(RowIndex, ColIndex)>,
  18. ) -> (usize, Duration) {
  19. let now = Instant::now();
  20. let mut antinodes = FxHashSet::default();
  21. for freq in map.get_unique_freqs() {
  22. let filtered_map = map.filter_freq(freq);
  23. let specific_antinodes = generator(&filtered_map);
  24. antinodes = antinodes
  25. .union(&specific_antinodes)
  26. .map(|f| *f)
  27. .collect::<FxHashSet<_>>();
  28. }
  29. let ans = antinodes.len();
  30. (ans, now.elapsed())
  31. }
  32.  
  33. type RowIndex = isize;
  34. type ColIndex = isize;
  35.  
  36. #[derive(Debug, Clone)]
  37. struct Map {
  38. freq_if_unique: Option<char>,
  39. antennae: FxHashMap<(RowIndex, ColIndex), char>,
  40. bounds: (usize, usize),
  41. }
  42.  
  43. impl Map {
  44. fn from_str(lines: &str) -> Self {
  45. let mut antennae = FxHashMap::default();
  46. lines.lines().enumerate().for_each(|(row, line)| {
  47. line.chars().enumerate().for_each(|(col, c)| {
  48. if c != '.' {
  49. antennae.insert((row as isize, col as isize), c);
  50. }
  51. });
  52. });
  53. Self {
  54. freq_if_unique: None,
  55. antennae,
  56. bounds: (lines.lines().count(), lines.lines().next().unwrap().len()),
  57. }
  58. }
  59.  
  60. fn get_unique_freqs(&self) -> Vec<char> {
  61. let mut freqs = Vec::new();
  62. self.antennae.values().for_each(|&c| {
  63. if !freqs.contains(&c) {
  64. freqs.push(c);
  65. }
  66. });
  67. freqs
  68. }
  69.  
  70. fn filter_freq(&self, char: char) -> Self {
  71. let antennae = self
  72. .antennae
  73. .iter()
  74. .filter(|(_, &c)| c == char)
  75. .map(|(&k, &v)| (k, v))
  76. .collect();
  77. Self {
  78. freq_if_unique: Some(char),
  79. antennae,
  80. bounds: self.bounds,
  81. }
  82. }
  83.  
  84. fn generate_antinodes_p1(&self) -> FxHashSet<(RowIndex, ColIndex)> {
  85. let mut antinodes: FxHashSet<(RowIndex, ColIndex)> = FxHashSet::default();
  86. let node_pairs = self.antennae.keys().combinations(2);
  87. for pair in node_pairs {
  88. let (node1, node2) = (pair[0], pair[1]);
  89. let (row1, col1) = node1;
  90. let (row2, col2) = node2;
  91. let vec = (row2 - row1, col2 - col1);
  92. let mut point = (row1 + vec.0, col1 + vec.1);
  93. while point.0 >= 0
  94. && point.0 < self.bounds.0 as isize
  95. && point.1 >= 0
  96. && point.1 < self.bounds.1 as isize
  97. {
  98. let distance_1 = distance(node1, &point);
  99. let distance_2 = distance(node2, &point);
  100. if check_distance(distance_1, distance_2) {
  101. antinodes.insert(point);
  102. }
  103. point = (point.0 + vec.0, point.1 + vec.1);
  104. }
  105.  
  106. let mut point = (row1 - vec.0, col1 - vec.1);
  107. while point.0 >= 0
  108. && point.0 < self.bounds.0 as isize
  109. && point.1 >= 0
  110. && point.1 < self.bounds.1 as isize
  111. {
  112. let distance_1 = distance(node1, &point);
  113. let distance_2 = distance(node2, &point);
  114. if check_distance(distance_1, distance_2) {
  115. antinodes.insert(point);
  116. }
  117. point = (point.0 - vec.0, point.1 - vec.1);
  118. }
  119. }
  120. antinodes
  121. }
  122.  
  123. fn generate_antinodes_p2(&self) -> FxHashSet<(RowIndex, ColIndex)> {
  124. let mut antinodes: FxHashSet<(RowIndex, ColIndex)> = FxHashSet::default();
  125. let node_pairs = self.antennae.keys().combinations(2);
  126. for pair in node_pairs {
  127. let (node1, node2) = (pair[0], pair[1]);
  128. let (row1, col1) = node1;
  129. let (row2, col2) = node2;
  130. let vec = (row2 - row1, col2 - col1);
  131. let mut point = (*row1, *col1);
  132. while point.0 >= 0
  133. && point.0 < self.bounds.0 as isize
  134. && point.1 >= 0
  135. && point.1 < self.bounds.1 as isize
  136. {
  137. antinodes.insert(point);
  138. point = (point.0 + vec.0, point.1 + vec.1);
  139. }
  140.  
  141. let mut point = (*row1, *col1);
  142. while point.0 >= 0
  143. && point.0 < self.bounds.0 as isize
  144. && point.1 >= 0
  145. && point.1 < self.bounds.1 as isize
  146. {
  147. antinodes.insert(point);
  148. point = (point.0 - vec.0, point.1 - vec.1);
  149. }
  150. }
  151. antinodes
  152. }
  153. }
  154.  
  155. const fn distance(
  156. (row1, col1): &(RowIndex, ColIndex),
  157. (row2, col2): &(RowIndex, ColIndex),
  158. ) -> usize {
  159. ((*row1 - *row2).abs() + (*col1 - *col2).abs()) as usize
  160. }
  161.  
  162. const fn check_distance(distance_1: usize, distance_2: usize) -> bool {
  163. distance_1 * 2 == distance_2 || distance_2 * 2 == distance_1
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement