Skip to content

Commit 109512e

Browse files
committed
chore: WIP y2025::day_09::part_2
1 parent 234dc27 commit 109512e

File tree

1 file changed

+70
-56
lines changed

1 file changed

+70
-56
lines changed

aoclp_solutions/src/y2025/day_09.rs

Lines changed: 70 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::cmp::{max, min};
2-
use std::collections::{BTreeSet, HashSet};
2+
use std::collections::BTreeSet;
33
use std::iter::successors;
44

55
use aoclp::positioning::direction::four_points::Direction4;
66
use aoclp::positioning::pt::{rectangular_area, Pt};
77
use aoclp::solvers_impl::input::safe_get_input_as_many;
8-
use itertools::Itertools;
8+
use itertools::{chain, Either, Itertools};
99
use aoclp::positioning::direction::Direction;
1010

1111
pub fn part_1() -> i64 {
@@ -26,7 +26,7 @@ pub fn part_2() -> i64 {
2626
Pt::new(min(a.x, b.x), min(a.y, b.y)),
2727
Pt::new(max(a.x, b.x), min(a.y, b.y)),
2828
Pt::new(max(a.x, b.x), max(a.y, b.y)),
29-
Pt::new(max(a.x, b.x), min(a.y, b.y)),
29+
Pt::new(min(a.x, b.x), max(a.y, b.y)),
3030
Pt::new(min(a.x, b.x), min(a.y, b.y)),
3131
];
3232
let edges: BTreeSet<_> = corners
@@ -49,46 +49,46 @@ pub fn part_2() -> i64 {
4949
.unwrap();
5050
println!("Largest rectangle is ({a}, {b}) area: {area}");
5151

52-
{
53-
let red_tiles = input();
54-
let min_x = red_tiles.iter().map(|a| a.x).min().unwrap() - 2;
55-
let max_x = red_tiles.iter().map(|a| a.x).max().unwrap() - 2;
56-
let min_y = red_tiles.iter().map(|a| a.y).min().unwrap() + 2;
57-
let max_y = red_tiles.iter().map(|a| a.y).max().unwrap() + 2;
58-
let red_tiles: HashSet<_> = red_tiles.iter().copied().collect();
59-
let corners = vec![
60-
Pt::new(min(a.x, b.x), min(a.y, b.y)),
61-
Pt::new(max(a.x, b.x), min(a.y, b.y)),
62-
Pt::new(max(a.x, b.x), max(a.y, b.y)),
63-
Pt::new(max(a.x, b.x), min(a.y, b.y)),
64-
Pt::new(min(a.x, b.x), min(a.y, b.y)),
65-
];
66-
let edges: BTreeSet<_> = corners
67-
.into_iter()
68-
.tuple_windows()
69-
.flat_map(|(a, b)| {
70-
let displacement = Pt::new((b.x - a.x).signum(), (b.y - a.y).signum());
71-
successors(Some(a), move |&p| (p != b).then_some(p + displacement))
72-
})
73-
.collect();
74-
75-
for y in min_x..=max_y {
76-
for x in min_y..=max_x {
77-
let pt = Pt::new(x, y);
78-
if red_tiles.contains(&pt) {
79-
print!("#");
80-
} else if red_zone.contains(&pt) {
81-
print!("!");
82-
} else if edges.contains(&pt) {
83-
print!("O");
84-
} else {
85-
print!(".");
86-
}
87-
}
88-
println!();
89-
}
90-
println!();
91-
}
52+
// {
53+
// let red_tiles = input();
54+
// let min_x = red_tiles.iter().map(|a| a.x).min().unwrap() - 2;
55+
// let max_x = red_tiles.iter().map(|a| a.x).max().unwrap() - 2;
56+
// let min_y = red_tiles.iter().map(|a| a.y).min().unwrap() + 2;
57+
// let max_y = red_tiles.iter().map(|a| a.y).max().unwrap() + 2;
58+
// let red_tiles: HashSet<_> = red_tiles.iter().copied().collect();
59+
// let corners = vec![
60+
// Pt::new(min(a.x, b.x), min(a.y, b.y)),
61+
// Pt::new(max(a.x, b.x), min(a.y, b.y)),
62+
// Pt::new(max(a.x, b.x), max(a.y, b.y)),
63+
// Pt::new(max(a.x, b.x), min(a.y, b.y)),
64+
// Pt::new(min(a.x, b.x), min(a.y, b.y)),
65+
// ];
66+
// let edges: BTreeSet<_> = corners
67+
// .into_iter()
68+
// .tuple_windows()
69+
// .flat_map(|(a, b)| {
70+
// let displacement = Pt::new((b.x - a.x).signum(), (b.y - a.y).signum());
71+
// successors(Some(a), move |&p| (p != b).then_some(p + displacement))
72+
// })
73+
// .collect();
74+
//
75+
// for y in min_x..=max_y {
76+
// for x in min_y..=max_x {
77+
// let pt = Pt::new(x, y);
78+
// if red_tiles.contains(&pt) {
79+
// print!("#");
80+
// } else if red_zone.contains(&pt) {
81+
// print!("!");
82+
// } else if edges.contains(&pt) {
83+
// print!("O");
84+
// } else {
85+
// print!(".");
86+
// }
87+
// }
88+
// println!();
89+
// }
90+
// println!();
91+
// }
9292

9393
area
9494
}
@@ -101,26 +101,40 @@ fn build_red_zone(red_tiles: &[Pt]) -> impl Iterator<Item = Pt> + use<'_> {
101101
.next()
102102
.unwrap();
103103

104+
let get_direction = |a: Pt, b: Pt| match ((b.x - a.x).signum(), (b.y - a.y).signum()) {
105+
(1, 0) => Direction4::Right,
106+
(0, 1) => Direction4::Down,
107+
(-1, 0) => Direction4::Left,
108+
(0, -1) => Direction4::Up,
109+
_ => unreachable!(),
110+
};
111+
104112
red_tiles
105113
.iter()
106114
.copied()
107115
.cycle()
108116
.skip_while(move |&p| p != starting_point)
109-
.enumerate()
110-
.take_while(move |&(i, p)| i == 0 || p != starting_point)
111-
.map(|(_, p)| p)
117+
.take(red_tiles.len() + 1)
112118
.tuple_windows()
113-
.flat_map(|(a, b)| {
114-
let direction = match ((b.x - a.x).signum(), (b.y - a.y).signum()) {
115-
(1, 0) => Direction4::Right,
116-
(0, 1) => Direction4::Down,
117-
(-1, 0) => Direction4::Left,
118-
(0, -1) => Direction4::Up,
119-
_ => unreachable!(),
120-
};
121-
successors(Some(a), move |&p| (p != b).then_some(p + direction))
119+
.flat_map(move |(a, b, c)| {
120+
let direction = get_direction(a, b);
121+
let turning_left = get_direction(b, c) == direction.turn_left();
122+
123+
let red_zone_path = successors(Some(a), move |&p| (p != b).then_some(p + direction))
122124
.skip(1)
123-
.map(move |p| p + (direction.turn_left()))
125+
.map(move |p| p + (direction.turn_left()));
126+
if turning_left {
127+
Either::Left(red_zone_path)
128+
} else {
129+
Either::Right(chain(
130+
red_zone_path,
131+
vec![
132+
b + direction.turn_left(),
133+
b + direction + direction.turn_left(),
134+
b + direction,
135+
],
136+
))
137+
}
124138
})
125139
}
126140

0 commit comments

Comments
 (0)