Skip to content

Commit 4796f10

Browse files
committed
[2025] Cleanup day 9
1 parent 54943f9 commit 4796f10

File tree

1 file changed

+41
-44
lines changed

1 file changed

+41
-44
lines changed

aoc_2025/src/day_09.rs

Lines changed: 41 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ use nd_vec::{Vec2, vector};
77
solution!("Movie Theater", 9);
88

99
fn part_a(input: &str) -> Answer {
10-
parse(input)
11-
.iter()
12-
.combinations(2)
13-
.map(|x| (x[0].x().abs_diff(x[1].x()) + 1) * (x[0].y().abs_diff(x[1].y()) + 1))
10+
(parse(input).iter())
11+
.tuple_combinations()
12+
.map(|(a, b)| area(a, b))
1413
.max()
1514
.unwrap()
1615
.into()
@@ -20,54 +19,21 @@ fn part_b(input: &str) -> Answer {
2019
let red = parse(input);
2120
red.iter()
2221
.tuple_combinations()
23-
.map(|(a, b)| {
24-
(
25-
(a.x().abs_diff(b.x()) + 1) * (a.y().abs_diff(b.y()) + 1),
26-
(a, b),
27-
)
28-
})
22+
.map(|(a, b)| (area(a, b), (a, b)))
2923
.sorted_by_key(|(area, _)| Reverse(*area))
3024
.find(|(_area, (a, b))| {
31-
let min = vector!(a.x().min(b.x()), a.y().min(b.y()));
32-
let max = vector!(a.x().max(b.x()), a.y().max(b.y()));
33-
34-
for (&α, &β) in red.iter().chain(iter::once(&red[0])).tuple_windows() {
35-
let lmin = vector!(α.x().min(β.x()), α.y().min(β.y()));
36-
let lmax = vector!(α.x().max(β.x()), α.y().max(β.y()));
37-
38-
if α.x() == β.x() {
39-
let x = β.x();
40-
if ((lmin.y() < min.y() && lmax.y() > min.y())
41-
|| (lmin.y() < max.y() && lmax.y() > max.y())
42-
|| (lmin.y() >= min.y() && lmax.y() <= max.y()))
43-
&& x > min.x()
44-
&& x < max.x()
45-
{
46-
return false;
47-
}
48-
} else if α.y() == β.y() {
49-
let y = β.y();
50-
if ((lmin.x() < min.x() && lmax.x() > min.x())
51-
|| (lmin.x() < max.x() && lmax.x() > max.x())
52-
|| (lmin.x() >= min.x() && lmax.x() <= max.x()))
53-
&& y > min.y()
54-
&& y < max.y()
55-
{
56-
return false;
57-
}
58-
}
59-
}
60-
61-
true
25+
let bounds = bounds(a, b);
26+
!red.iter()
27+
.chain(iter::once(&red[0]))
28+
.tuple_windows()
29+
.any(|line| intersecting_line(line, bounds))
6230
})
6331
.unwrap()
6432
.0
6533
.into()
6634
}
6735

68-
// not: >1565730054
69-
70-
fn parse(input: &str) -> Vec<Vec2<i64>> {
36+
fn parse(input: &str) -> Vec<Vec2<u64>> {
7137
(input.lines())
7238
.map(|x| {
7339
let (x, y) = x.split_once(',').unwrap();
@@ -76,6 +42,37 @@ fn parse(input: &str) -> Vec<Vec2<i64>> {
7642
.collect::<Vec<_>>()
7743
}
7844

45+
fn area(a: &Vec2<u64>, b: &Vec2<u64>) -> u64 {
46+
(a.x().abs_diff(b.x()) + 1) * (a.y().abs_diff(b.y()) + 1)
47+
}
48+
49+
fn bounds(a: &Vec2<u64>, b: &Vec2<u64>) -> (Vec2<u64>, Vec2<u64>) {
50+
(
51+
vector!(a.x().min(b.x()), a.y().min(b.y())),
52+
vector!(a.x().max(b.x()), a.y().max(b.y())),
53+
)
54+
}
55+
56+
fn intersecting_line(
57+
(la, lb): (&Vec2<u64>, &Vec2<u64>),
58+
(min, max): (Vec2<u64>, Vec2<u64>),
59+
) -> bool {
60+
let (lmin, lmax) = bounds(la, lb);
61+
62+
la.x() == lb.x() // horizontal line
63+
&& (((lmin.y() < min.y() && lmax.y() > min.y())
64+
|| (lmin.y() < max.y() && lmax.y() > max.y())
65+
|| (lmin.y() >= min.y() && lmax.y() <= max.y()))
66+
&& la.x() > min.x()
67+
&& la.x() < max.x())
68+
|| la.y() == lb.y() // vertical line
69+
&& (((lmin.x() < min.x() && lmax.x() > min.x())
70+
|| (lmin.x() < max.x() && lmax.x() > max.x())
71+
|| (lmin.x() >= min.x() && lmax.x() <= max.x()))
72+
&& la.y() > min.y()
73+
&& la.y() < max.y())
74+
}
75+
7976
#[cfg(test)]
8077
mod test {
8178
use indoc::indoc;

0 commit comments

Comments
 (0)