Skip to content

Commit f2ab58d

Browse files
committed
feat(07/2025): solve second part for example
1 parent 5d2209a commit f2ab58d

File tree

1 file changed

+117
-48
lines changed

1 file changed

+117
-48
lines changed

src/solutions/year2025/day07.rs

Lines changed: 117 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,20 @@ const BEAM: char = '|';
1111

1212
pub struct Day07;
1313

14+
type Splits = u16;
15+
type Timelines = u16;
16+
1417
impl Solution for Day07 {
1518
fn part_one(&self, input: &str) -> String {
1619
let (splits, _) = self.run(input);
1720

1821
splits.to_string()
1922
}
2023

21-
fn part_two(&self, _input: &str) -> String {
22-
String::from("0")
24+
fn part_two(&self, input: &str) -> String {
25+
let (_, timelines) = self.run(input);
26+
27+
timelines.to_string()
2328
}
2429
}
2530

@@ -30,31 +35,33 @@ impl Day07 {
3035
Grid::from(without_redundant_lines.as_str())
3136
}
3237

33-
fn run(&self, input: &str) -> (u16, u16) {
38+
fn run(&self, input: &str) -> (Splits, Timelines) {
3439
let grid = self.parse(input);
3540
let rows_range = grid.rows_range();
3641
let start = grid.get_first_position(&START).unwrap();
3742

3843
let splitters: HashSet<Point> = grid.get_all_positions(&SPLITTER).into_iter().collect();
3944

45+
let mut split_beams: Vec<Beam> = Vec::new();
4046
let mut finished_beams: Vec<Beam> = Vec::new();
41-
let mut current_beams: VecDeque<Beam> = VecDeque::from(vec![start.into()]);
42-
let mut splits = 0u16;
47+
let mut current_beams: VecDeque<Beam> = VecDeque::from(vec![Beam::new(start)]);
4348

44-
while let Some(current_beam) = current_beams.pop_front() {
45-
if finished_beams
46-
.iter()
47-
.chain(current_beams.iter())
48-
.any(|beam| beam.collides(&current_beam))
49+
'while_loop: while let Some(current_beam) = current_beams.pop_front() {
50+
for beam in split_beams
51+
.iter_mut()
52+
.chain(current_beams.iter_mut())
53+
.chain(finished_beams.iter_mut())
4954
{
50-
continue;
55+
if current_beam.collides(beam) {
56+
*beam = beam.merge(current_beam);
57+
continue 'while_loop;
58+
}
5159
}
5260

5361
let down = current_beam.down();
5462

5563
if splitters.contains(&down.current()) {
56-
finished_beams.push(current_beam);
57-
splits += 1;
64+
split_beams.push(current_beam);
5865

5966
for split in down.split() {
6067
current_beams.push_back(split);
@@ -68,10 +75,15 @@ impl Day07 {
6875
continue;
6976
}
7077

71-
current_beams.push_front(down);
78+
current_beams.push_back(down);
7279
}
7380

74-
(splits, 0)
81+
(
82+
split_beams.len() as Splits,
83+
finished_beams
84+
.iter()
85+
.fold(0, |acc, beam| acc + beam.timelines),
86+
)
7587
}
7688
}
7789

@@ -88,9 +100,17 @@ fn print(grid: &Grid<char>, beams: &[Beam]) {
88100
#[derive(Copy, Clone, Debug)]
89101
struct Beam {
90102
line: Line,
103+
timelines: u16,
91104
}
92105

93106
impl Beam {
107+
fn new(point: Point) -> Self {
108+
Self {
109+
line: Line::new(point, point),
110+
timelines: 1,
111+
}
112+
}
113+
94114
fn collides(&self, other: &Self) -> bool {
95115
let other = other.current();
96116

@@ -103,6 +123,7 @@ impl Beam {
103123
fn down(&self) -> Self {
104124
Self {
105125
line: Line::new(self.line.start(), self.line.end().south()),
126+
timelines: self.timelines,
106127
}
107128
}
108129

@@ -111,22 +132,25 @@ impl Beam {
111132
}
112133

113134
fn split(&self) -> Vec<Beam> {
114-
vec![self.current().west().into(), self.current().east().into()]
115-
}
116-
}
117-
118-
impl From<Point> for Beam {
119-
fn from(value: Point) -> Self {
120-
Self {
121-
line: Line::new(value, value),
122-
}
135+
let west = self.current().west();
136+
let east = self.current().east();
137+
138+
vec![
139+
Self {
140+
line: Line::new(west, west),
141+
timelines: self.timelines,
142+
},
143+
Self {
144+
line: Line::new(east, east),
145+
timelines: self.timelines,
146+
},
147+
]
123148
}
124-
}
125149

126-
impl From<(Point, Point)> for Beam {
127-
fn from(value: (Point, Point)) -> Self {
150+
fn merge(&self, other: Self) -> Self {
128151
Self {
129-
line: Line::new(value.0, value.1),
152+
line: self.line,
153+
timelines: self.timelines + other.timelines,
130154
}
131155
}
132156
}
@@ -181,28 +205,33 @@ mod tests {
181205
assert_eq!("21", Day07.part_one(EXAMPLE));
182206
}
183207

208+
#[test]
209+
fn part_two_example_test() {
210+
assert_eq!("40", Day07.part_two(EXAMPLE));
211+
}
212+
184213
#[test]
185214
fn beam_collides() {
186-
let beam: Beam = (Point::new(3, 0), Point::new(3, 3)).into();
187-
188-
assert!(!beam.collides(&Beam::from(Point::new(3, -1))));
189-
assert!(beam.collides(&Beam::from(Point::new(3, 0))));
190-
assert!(beam.collides(&Beam::from(Point::new(3, 1))));
191-
assert!(beam.collides(&Beam::from(Point::new(3, 2))));
192-
assert!(beam.collides(&Beam::from(Point::new(3, 3))));
193-
assert!(!beam.collides(&Beam::from(Point::new(3, 4))));
194-
195-
assert!(!beam.collides(&Beam::from(Point::new(2, 0))));
196-
assert!(!beam.collides(&Beam::from(Point::new(2, 1))));
197-
assert!(!beam.collides(&Beam::from(Point::new(2, 2))));
198-
assert!(!beam.collides(&Beam::from(Point::new(2, 3))));
199-
assert!(!beam.collides(&Beam::from(Point::new(2, 4))));
200-
201-
assert!(!beam.collides(&Beam::from(Point::new(4, 0))));
202-
assert!(!beam.collides(&Beam::from(Point::new(4, 1))));
203-
assert!(!beam.collides(&Beam::from(Point::new(4, 2))));
204-
assert!(!beam.collides(&Beam::from(Point::new(4, 3))));
205-
assert!(!beam.collides(&Beam::from(Point::new(4, 4))));
215+
let beam: Beam = Beam::new(Point::new(3, 0)).down().down().down();
216+
217+
assert!(!beam.collides(&Beam::new(Point::new(3, -1))));
218+
assert!(beam.collides(&Beam::new(Point::new(3, 0))));
219+
assert!(beam.collides(&Beam::new(Point::new(3, 1))));
220+
assert!(beam.collides(&Beam::new(Point::new(3, 2))));
221+
assert!(beam.collides(&Beam::new(Point::new(3, 3))));
222+
assert!(!beam.collides(&Beam::new(Point::new(3, 4))));
223+
224+
assert!(!beam.collides(&Beam::new(Point::new(2, 0))));
225+
assert!(!beam.collides(&Beam::new(Point::new(2, 1))));
226+
assert!(!beam.collides(&Beam::new(Point::new(2, 2))));
227+
assert!(!beam.collides(&Beam::new(Point::new(2, 3))));
228+
assert!(!beam.collides(&Beam::new(Point::new(2, 4))));
229+
230+
assert!(!beam.collides(&Beam::new(Point::new(4, 0))));
231+
assert!(!beam.collides(&Beam::new(Point::new(4, 1))));
232+
assert!(!beam.collides(&Beam::new(Point::new(4, 2))));
233+
assert!(!beam.collides(&Beam::new(Point::new(4, 3))));
234+
assert!(!beam.collides(&Beam::new(Point::new(4, 4))));
206235
}
207236

208237
const EXAMPLE_FROM_REDDIT: &str = r#"..S..
@@ -235,6 +264,11 @@ mod tests {
235264
assert_eq!("4", Day07.part_one(EXAMPLE_FROM_REDDIT2));
236265
}
237266

267+
#[test]
268+
fn part_two_example_from_reddit2() {
269+
assert_eq!("6", Day07.part_two(EXAMPLE_FROM_REDDIT2));
270+
}
271+
238272
const MY_EXAMPLE: &str = r#"..S..
239273
.....
240274
..^..
@@ -249,6 +283,11 @@ mod tests {
249283
assert_eq!("3", Day07.part_one(MY_EXAMPLE));
250284
}
251285

286+
#[test]
287+
fn part_two_my_example() {
288+
assert_eq!("4", Day07.part_two(MY_EXAMPLE));
289+
}
290+
252291
const MY_EXAMPLE2: &str = r#"..S..
253292
.....
254293
..^..
@@ -264,4 +303,34 @@ mod tests {
264303
fn part_one_my_example2() {
265304
assert_eq!("6", Day07.part_one(MY_EXAMPLE2));
266305
}
306+
307+
const MY_EXAMPLE3: &str = r#"...S...
308+
.......
309+
...^...
310+
.......
311+
..^.^..
312+
.......
313+
.^...^.
314+
......."#;
315+
316+
#[test]
317+
fn part_two_my_example3() {
318+
assert_eq!("6", Day07.part_two(MY_EXAMPLE3));
319+
}
320+
321+
const MY_EXAMPLE3_EXTENDED: &str = r#"...S...
322+
.......
323+
...^...
324+
.......
325+
..^.^..
326+
.......
327+
.^...^.
328+
.......
329+
...^...
330+
......."#;
331+
332+
#[test]
333+
fn part_two_my_example3_extended() {
334+
assert_eq!("8", Day07.part_two(MY_EXAMPLE3_EXTENDED));
335+
}
267336
}

0 commit comments

Comments
 (0)