Skip to content

Commit bdfe415

Browse files
committed
2025 09.2
1 parent 4374364 commit bdfe415

File tree

1 file changed

+13
-108
lines changed

1 file changed

+13
-108
lines changed

src/aoc/y2025/day09.rs

Lines changed: 13 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
// <https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12>.
88
// See the Licence for the specific language governing permissions and limitations under the Licence.
99

10-
use std::{collections::HashMap, fmt::Display};
10+
use std::fmt::Display;
1111

1212
use itertools::Itertools;
13-
use num::Integer;
1413

15-
use crate::{AoCError, BigCoord2D, CommonGrid, Coordinate, Coordinate2D, symbols};
14+
use crate::{AoCError, BigCoord2D, CommonGrid, Coordinate, symbols};
1615

1716
pub fn part_1(data: crate::DataIn) -> crate::AoCResult<String> {
1817
let coords: Vec<BigCoord2D> = data.map(|line| line.parse()).try_collect()?;
@@ -36,58 +35,6 @@ pub fn part_1(data: crate::DataIn) -> crate::AoCResult<String> {
3635
Ok(ret.to_string())
3736
}
3837

39-
/// Adapted from http://web.archive.org/web/20080812141848/http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/
40-
fn inside_polygon(point: BigCoord2D, polygon: &[BigCoord2D]) -> bool {
41-
polygon
42-
.iter()
43-
.tuple_windows()
44-
.filter(|(poly_a, poly_b)| {
45-
let poly_min = poly_a.get_min(poly_b);
46-
let poly_max = poly_a.get_max(poly_b);
47-
if point.y <= poly_min.y {
48-
// why does this only check y coords? who knows.
49-
return false;
50-
} else if point.x > poly_max.x || point.y > poly_max.y {
51-
return false;
52-
} else if poly_a.y == poly_b.y {
53-
// ????
54-
return false;
55-
}
56-
// mystery statement
57-
let xinters =
58-
(point.y - poly_a.y) * (poly_b.x - poly_a.x) / (poly_b.y - poly_a.y) + poly_a.x;
59-
poly_a.x == poly_b.x || point.x <= xinters
60-
})
61-
.count()
62-
.is_odd()
63-
}
64-
65-
fn cached_inside_polygon(
66-
point: BigCoord2D,
67-
polygon: &[BigCoord2D],
68-
prechecked: &mut HashMap<BigCoord2D, bool>,
69-
) -> bool {
70-
if let Some(result) = prechecked.get(&point) {
71-
return *result;
72-
}
73-
let result = inside_polygon(point, polygon);
74-
log::trace!(
75-
"Magic function says {point} is {} poly",
76-
if result { "inside" } else { "outside" }
77-
);
78-
prechecked.insert(point, result);
79-
result
80-
}
81-
82-
fn rectangulate(a: &BigCoord2D, b: &BigCoord2D) -> impl Iterator<Item = BigCoord2D> {
83-
log::trace!("wtf wtf {a} {b}");
84-
// I'm moderately sure I've written this code before but I don't know where it is
85-
(a.x..=b.x)
86-
.cartesian_product(a.y..=b.y)
87-
.map(BigCoord2D::from_tuple)
88-
.inspect(|c| log::trace!("wtf {c}"))
89-
}
90-
9138
pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
9239
let coords = {
9340
let mut coords: Vec<BigCoord2D> = data.map(|line| line.parse()).try_collect()?;
@@ -96,7 +43,7 @@ pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
9643
coords
9744
};
9845

99-
let mut prechecked: HashMap<BigCoord2D, bool> = coords
46+
let lines: Vec<BigCoord2D> = coords
10047
.iter()
10148
.tuple_windows()
10249
.flat_map(|(a, b)| {
@@ -110,7 +57,6 @@ pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
11057
(a.y..=b.y).map(|y| BigCoord2D { x, y }).collect_vec()
11158
}
11259
})
113-
.map(|c| (c, true))
11460
.collect();
11561

11662
// stupid test grid
@@ -139,7 +85,7 @@ pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
13985
}
14086

14187
let mut grid: SparseGrid<GridState, BigCoord2D> =
142-
prechecked.keys().map(|a| (*a, GridState::Green)).collect();
88+
lines.iter().map(|a| (*a, GridState::Green)).collect();
14389

14490
coords.iter().for_each(|c| {
14591
grid.set(*c, GridState::Red);
@@ -161,60 +107,19 @@ pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
161107
.inspect(|(dist, a, b)| {
162108
log::debug!("Square of area {dist} between {a} and {b}");
163109
})
164-
.find(|(_, a, b)| {
165-
rectangulate(a, b).all(|point| cached_inside_polygon(point, &coords, &mut prechecked))
110+
.filter(|(_, min, max)| {
111+
!coords
112+
.iter()
113+
.any(|c| c.x > min.x && c.y > min.y && c.x < max.x && c.y < max.y)
114+
})
115+
.find(|(_, min, max)| {
116+
!lines
117+
.iter()
118+
.any(|c| c.x > min.x && c.y > min.y && c.x < max.x && c.y < max.y)
166119
})
167120
.map(|(dist, _, _)| dist)
168121
.ok_or(AoCError::new("No valid rectangles?"))?;
169122

170-
// stupid test grid v2
171-
log::debug!("postchecked:\n{}", {
172-
use aoc_macros::VoidState;
173-
174-
use crate::SparseGrid;
175-
176-
#[derive(Debug, VoidState)]
177-
enum GridState {
178-
#[void]
179-
Void,
180-
Red,
181-
Green,
182-
White,
183-
}
184-
185-
impl Display for GridState {
186-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
187-
match self {
188-
Self::Void => symbols::VOID,
189-
Self::Red => symbols::BLOCK,
190-
Self::Green => symbols::SHADE_DARK,
191-
Self::White => symbols::SHADE_LIGHT,
192-
}
193-
.fmt(f)
194-
}
195-
}
196-
197-
let mut grid: SparseGrid<GridState, BigCoord2D> = prechecked
198-
.iter()
199-
.map(|(coord, state)| {
200-
(
201-
*coord,
202-
if *state {
203-
GridState::Green
204-
} else {
205-
GridState::White
206-
},
207-
)
208-
})
209-
.collect();
210-
211-
coords.iter().for_each(|c| {
212-
grid.set(*c, GridState::Red);
213-
});
214-
215-
grid
216-
});
217-
218123
Ok(ret.to_string())
219124
}
220125

0 commit comments

Comments
 (0)