Skip to content

Commit 784eddd

Browse files
committed
chore: WIP optimization of y2025::day_09::part_2
1 parent 3280843 commit 784eddd

File tree

1 file changed

+89
-15
lines changed

1 file changed

+89
-15
lines changed

aoclp_solutions/src/y2025/day_09.rs

Lines changed: 89 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use std::collections::HashSet;
12
use std::fmt;
23
use std::iter::once;
34

45
use aoclp::positioning::direction::four_points::Direction4;
56
use aoclp::positioning::direction::{Direction, MovementDirection};
67
use aoclp::positioning::pt::{min_max, rectangle_corners, rectangular_area, Pt};
7-
use aoclp::solvers_impl::input::safe_get_input_as_many;
8+
use aoclp::solvers_impl::input::{safe_get_input_as_many, Input};
89
use itertools::Itertools;
910
use strum::IntoEnumIterator;
1011

@@ -21,21 +22,85 @@ pub fn part_2() -> i64 {
2122
let red_tiles = input();
2223
let walls = walls(&red_tiles).collect_vec();
2324

24-
red_tiles
25-
.into_iter()
25+
let valid_rectangle = |a: Pt, b: Pt| {
26+
let corners = rectangle_corners(a, b);
27+
corners
28+
.into_iter()
29+
.chain(once(corners[0]))
30+
.tuple_windows()
31+
.map(|(a, b)| GridLine::from_endpoints(a, b))
32+
.all(|line| !walls.iter().any(|w| w.intersects(line)))
33+
};
34+
35+
let area = red_tiles
36+
.iter()
37+
.copied()
2638
.array_combinations()
27-
.filter(|[a, b]| {
28-
let corners = rectangle_corners(*a, *b);
29-
corners
30-
.into_iter()
31-
.chain(once(corners[0]))
32-
.tuple_windows()
33-
.map(|(a, b)| GridLine::from_endpoints(a, b))
34-
.all(|line| !walls.iter().any(|w| w.intersects(line)))
35-
})
39+
.filter(|[a, b]| valid_rectangle(*a, *b))
3640
.map(|[a, b]| rectangular_area(a, b))
3741
.max()
38-
.unwrap()
42+
.unwrap();
43+
44+
let matching_rects = red_tiles
45+
.iter()
46+
.copied()
47+
.array_combinations()
48+
.map(|[a, b]| (a, b, rectangular_area(a, b)))
49+
.filter(|(_, _, ar)| *ar == area)
50+
.filter(|(a, b, _)| valid_rectangle(*a, *b))
51+
.collect_vec();
52+
53+
println!("The largest rectangle has an area of {area}. Matching rectangles:");
54+
for (a, b, _) in matching_rects {
55+
println!(" {a} - {b}");
56+
}
57+
58+
// let line_pts = |line: GridLine| {
59+
// match line {
60+
// GridLine::Horizontal { y, left_x, right_x } => {
61+
// (left_x..=right_x).map(|x| Pt::new(x, y)).collect_vec()
62+
// },
63+
// GridLine::Vertical { x, top_y, bottom_y } => {
64+
// (top_y..=bottom_y).map(|y| Pt::new(x, y)).collect_vec()
65+
// },
66+
// GridLine::Point(p) => vec![p],
67+
// }
68+
// };
69+
//
70+
// let red_tiles_s: HashSet<_> = red_tiles.iter().copied().collect();
71+
// let path_s: HashSet<_> = red_tiles
72+
// .iter()
73+
// .copied()
74+
// .chain(once(red_tiles[0]))
75+
// .tuple_windows()
76+
// .flat_map(|(a, b)| line_pts(GridLine::from_endpoints(a, b)))
77+
// .collect();
78+
// let walls_s: HashSet<_> = walls
79+
// .iter()
80+
// .flat_map(|w| line_pts(*w))
81+
// .collect();
82+
//
83+
// let max_x = red_tiles.iter().map(|p| p.x).max().unwrap() + 3;
84+
// let max_y = red_tiles.iter().map(|p| p.y).max().unwrap() + 3;
85+
//
86+
// for y in 0..=max_y {
87+
// for x in 0..=max_x {
88+
// let p = Pt::new(x, y);
89+
// if red_tiles_s.contains(&p) {
90+
// print!("#");
91+
// } else if walls_s.contains(&p) {
92+
// print!("!");
93+
// } else if path_s.contains(&p) {
94+
// print!("X");
95+
// } else {
96+
// print!(".");
97+
// }
98+
// }
99+
// println!();
100+
// }
101+
// println!();
102+
103+
area
39104
}
40105

41106
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -142,18 +207,23 @@ fn walls(red_tiles: &[Pt]) -> impl Iterator<Item = GridLine> + use<'_> {
142207
.skip_while(move |&p| p != starting_point)
143208
.take(red_tiles.len() + 2)
144209
.tuple_windows()
145-
.map(move |(a, b, c)| {
210+
.scan(true, move |turned_right, (a, b, c)| {
146211
let direction = get_direction(a, b);
147212
let turning_right = get_direction(b, c) == direction.turn_right();
148213

149214
let mut line = GridLine::from_endpoints(
150215
a + direction + direction.turn_left(),
151216
b + direction.turn_around() + direction.turn_left(),
152217
);
218+
if *turned_right {
219+
line = line.extend(direction.turn_around(), 1);
220+
}
153221
if turning_right {
154222
line = line.extend(direction, 2);
155223
}
156-
line
224+
225+
*turned_right = turning_right;
226+
Some(line)
157227
})
158228
}
159229

@@ -170,3 +240,7 @@ const EXAMPLE: &str = "\
170240
fn input() -> Vec<Pt> {
171241
safe_get_input_as_many(2025, 9)
172242
}
243+
244+
fn example() -> Vec<Pt> {
245+
Input::for_example(EXAMPLE).safe_into_many()
246+
}

0 commit comments

Comments
 (0)