Skip to content

Commit 863ae76

Browse files
committed
feat(08/2024): solve second part
1 parent b3d1ec2 commit 863ae76

File tree

2 files changed

+90
-10
lines changed

2 files changed

+90
-10
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
| [Day 5: Print Queue](src/solutions/year2024/day05.rs) | ⭐⭐ | 3.151 | 11.874 |
1919
| [Day 6: Guard Gallivant](src/solutions/year2024/day06.rs) || 8.738 | |
2020
| [Day 7: Bridge Repair](src/solutions/year2024/day07.rs) | ⭐⭐ | 1.198 | 219.754 |
21-
| [Day 8: Resonant Collinearity](src/solutions/year2024/day08.rs) || 0.883 | |
21+
| [Day 8: Resonant Collinearity](src/solutions/year2024/day08.rs) | | 0.883 | 1.238 |
2222

2323
# 2023
2424

src/solutions/year2024/day08.rs

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::solutions::Solution;
22
use crate::utils::grid::Grid;
33
use crate::utils::point::Point;
4-
use itertools::Itertools;
4+
use crate::utils::surface_range::SurfaceRange;
5+
use itertools::{concat, Itertools};
56

67
pub struct Day08;
78

@@ -17,37 +18,81 @@ impl Solution for Day08 {
1718
points
1819
.iter()
1920
.combinations(2)
20-
.flat_map(|pair| self.antinodes(*pair[0], *pair[1]))
21+
.flat_map(|pair| self.antinodes_part_one(*pair[0], *pair[1], &surface_range))
2122
.collect::<Vec<Point>>()
2223
})
23-
.filter(|p| surface_range.contains(*p))
2424
.unique()
2525
.count()
2626
.to_string()
2727
}
2828

29-
fn part_two(&self, _input: &str) -> String {
30-
String::from('0')
29+
fn part_two(&self, input: &str) -> String {
30+
let grid: Grid<char> = Grid::from(input);
31+
let surface_range = grid.surface_range();
32+
33+
grid.elements_with_points()
34+
.iter()
35+
.filter(|(element, _)| **element != '.')
36+
.flat_map(|(_, points)| {
37+
points
38+
.iter()
39+
.combinations(2)
40+
.flat_map(|pair| self.antinodes_part_two(*pair[0], *pair[1], &surface_range))
41+
.collect::<Vec<Point>>()
42+
})
43+
.unique()
44+
.count()
45+
.to_string()
3146
}
3247
}
3348

3449
impl Day08 {
35-
fn antinodes(&self, p1: Point, p2: Point) -> Vec<Point> {
50+
fn antinodes_part_one(&self, p1: Point, p2: Point, surface_range: &SurfaceRange) -> Vec<Point> {
3651
let diff = p1 - p2;
3752

3853
vec![p1 + diff, p1 - diff, p2 + diff, p2 - diff]
3954
.into_iter()
4055
.filter(|p| *p != p1 && *p != p2)
56+
.filter(|p| surface_range.contains(*p))
4157
.collect()
4258
}
59+
60+
fn antinodes_part_two(&self, p1: Point, p2: Point, surface_range: &SurfaceRange) -> Vec<Point> {
61+
let diff = p1 - p2;
62+
63+
let first = self.antipodes_in_dir(p1, diff, surface_range);
64+
let second = self.antipodes_in_dir(p2, -diff, surface_range);
65+
66+
let vec = concat(vec![first, second]);
67+
68+
vec.into_iter().unique().collect()
69+
}
70+
71+
fn antipodes_in_dir(
72+
&self,
73+
point: Point,
74+
diff: Point,
75+
surface_range: &SurfaceRange,
76+
) -> Vec<Point> {
77+
let mut vec = Vec::new();
78+
let mut current = point;
79+
80+
while surface_range.contains(current) {
81+
vec.push(current);
82+
83+
current = current + diff;
84+
}
85+
86+
vec
87+
}
4388
}
4489

4590
#[cfg(test)]
4691
mod tests {
4792
use crate::solutions::year2024::day08::Day08;
4893
use crate::solutions::Solution;
4994
use crate::utils::grid::Grid;
50-
use itertools::Itertools;
95+
use itertools::{concat, Itertools};
5196

5297
const EXAMPLE: &str = r#"............
5398
........0...
@@ -68,7 +113,12 @@ mod tests {
68113
}
69114

70115
#[test]
71-
fn antinodes() {
116+
fn part_two_example_test() {
117+
assert_eq!("34", Day08.part_two(EXAMPLE));
118+
}
119+
120+
#[test]
121+
fn antinodes_part_one() {
72122
const GRID: &str = r#"..........
73123
...#......
74124
..........
@@ -85,12 +135,42 @@ mod tests {
85135

86136
let (p1, p2) = elements.get(&'a').unwrap().iter().collect_tuple().unwrap();
87137

88-
let mut result = Day08.antinodes(*p1, *p2);
138+
let mut result = Day08.antinodes_part_one(*p1, *p2, &grid.surface_range());
89139
let mut expected = elements.get(&'#').unwrap().to_vec();
90140

91141
result.sort();
92142
expected.sort();
93143

94144
assert_eq!(expected, result);
95145
}
146+
147+
#[test]
148+
fn part_two_second_example() {
149+
const GRID: &str = r#"T....#....
150+
...T......
151+
.T....#...
152+
.........#
153+
..#.......
154+
..........
155+
...#......
156+
..........
157+
....#.....
158+
.........."#;
159+
160+
let grid: Grid<char> = Grid::from(GRID);
161+
let elements = grid.elements_with_points();
162+
163+
let (p1, p2, p3) = elements.get(&'T').unwrap().iter().collect_tuple().unwrap();
164+
165+
let result1 = Day08.antinodes_part_two(*p1, *p2, &grid.surface_range());
166+
let result2 = Day08.antinodes_part_two(*p1, *p3, &grid.surface_range());
167+
let result3 = Day08.antinodes_part_two(*p2, *p3, &grid.surface_range());
168+
169+
let result = concat(vec![result1, result2, result3])
170+
.iter()
171+
.unique()
172+
.count();
173+
174+
assert_eq!(9, result);
175+
}
96176
}

0 commit comments

Comments
 (0)