Skip to content

Commit 4c76182

Browse files
committed
AoC 2025 Day 9 - rust
1 parent f6b1b0c commit 4c76182

File tree

4 files changed

+135
-1
lines changed

4 files changed

+135
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
| python3 | [](src/main/python/AoC2025_01.py) | [](src/main/python/AoC2025_02.py) | [](src/main/python/AoC2025_03.py) | [](src/main/python/AoC2025_04.py) | [](src/main/python/AoC2025_05.py) | [](src/main/python/AoC2025_06.py) | [](src/main/python/AoC2025_07.py) | [](src/main/python/AoC2025_08.py) | [](src/main/python/AoC2025_09.py) | [](src/main/python/AoC2025_10.py) | [](src/main/python/AoC2025_11.py) | [](src/main/python/AoC2025_12.py) |
1414
| java | [](src/main/java/AoC2025_01.java) | [](src/main/java/AoC2025_02.java) | [](src/main/java/AoC2025_03.java) | [](src/main/java/AoC2025_04.java) | [](src/main/java/AoC2025_05.java) | [](src/main/java/AoC2025_06.java) | [](src/main/java/AoC2025_07.java) | [](src/main/java/AoC2025_08.java) | [](src/main/java/AoC2025_09.java) | [](src/main/java/AoC2025_10.java) | [](src/main/java/AoC2025_11.java) | [](src/main/java/AoC2025_12.java) |
1515
| bash | [](src/main/bash/AoC2025_01.sh) | [](src/main/bash/AoC2025_02.sh) | [](src/main/bash/AoC2025_03.sh) | [](src/main/bash/AoC2025_04.sh) | [](src/main/bash/AoC2025_05.sh) | [](src/main/bash/AoC2025_06.sh) | [](src/main/bash/AoC2025_07.sh) | | | | [](src/main/bash/AoC2025_11.sh) | [](src/main/bash/AoC2025_12.sh) |
16-
| rust | [](src/main/rust/AoC2025_01/src/main.rs) | [](src/main/rust/AoC2025_02/src/main.rs) | [](src/main/rust/AoC2025_03/src/main.rs) | [](src/main/rust/AoC2025_04/src/main.rs) | [](src/main/rust/AoC2025_05/src/main.rs) | [](src/main/rust/AoC2025_06/src/main.rs) | [](src/main/rust/AoC2025_07/src/main.rs) | [](src/main/rust/AoC2025_08/src/main.rs) | | | | |
16+
| rust | [](src/main/rust/AoC2025_01/src/main.rs) | [](src/main/rust/AoC2025_02/src/main.rs) | [](src/main/rust/AoC2025_03/src/main.rs) | [](src/main/rust/AoC2025_04/src/main.rs) | [](src/main/rust/AoC2025_05/src/main.rs) | [](src/main/rust/AoC2025_06/src/main.rs) | [](src/main/rust/AoC2025_07/src/main.rs) | [](src/main/rust/AoC2025_08/src/main.rs) | [](src/main/rust/AoC2025_09/src/main.rs) | | | |
1717
<!-- @END:ImplementationsTable:2025@ -->
1818

1919
## 2024
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "AoC2025_09"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
aoc = { path = "../aoc" }
8+
itertools = "0.11"
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#![allow(non_snake_case)]
2+
3+
use aoc::geometry::XY;
4+
use aoc::Puzzle;
5+
use itertools::Itertools;
6+
7+
struct Rectangle {
8+
min_x: usize,
9+
max_x: usize,
10+
min_y: usize,
11+
max_y: usize,
12+
}
13+
14+
impl Rectangle {
15+
fn from(p1: &XY, p2: &XY) -> Self {
16+
let min_x = p1.x().min(p2.x()) as usize;
17+
let max_x = p1.x().max(p2.x()) as usize;
18+
let min_y = p1.y().min(p2.y()) as usize;
19+
let max_y = p1.y().max(p2.y()) as usize;
20+
Rectangle {
21+
min_x,
22+
max_x,
23+
min_y,
24+
max_y,
25+
}
26+
}
27+
28+
fn area(&self) -> usize {
29+
(self.max_x - self.min_x + 1) * (self.max_y - self.min_y + 1)
30+
}
31+
32+
fn intersect(&self, other: &Self) -> bool {
33+
!(self.max_x <= other.min_x
34+
|| self.min_x >= other.max_x
35+
|| self.max_y <= other.min_y
36+
|| self.min_y >= other.max_y)
37+
}
38+
}
39+
40+
struct AoC2025_09;
41+
42+
impl AoC2025_09 {
43+
fn rectangles<'a>(
44+
reds: &'a <Self as Puzzle>::Input,
45+
) -> impl Iterator<Item = Rectangle> + 'a {
46+
reds.iter()
47+
.combinations(2)
48+
.map(move |c| Rectangle::from(c[0], c[1]))
49+
}
50+
}
51+
52+
impl aoc::Puzzle for AoC2025_09 {
53+
type Input = Vec<XY>;
54+
type Output1 = usize;
55+
type Output2 = usize;
56+
57+
aoc::puzzle_year_day!(2025, 9);
58+
59+
fn parse_input(&self, lines: Vec<String>) -> Self::Input {
60+
lines
61+
.iter()
62+
.map(|line| {
63+
let (x, y) = line.split_once(',').unwrap();
64+
XY::of(x.parse::<i32>().unwrap(), y.parse::<i32>().unwrap())
65+
})
66+
.collect::<Vec<_>>()
67+
}
68+
69+
fn part_1(&self, reds: &Self::Input) -> Self::Output1 {
70+
Self::rectangles(reds).map(|r| r.area()).max().unwrap()
71+
}
72+
73+
fn part_2(&self, reds: &Self::Input) -> Self::Output2 {
74+
let border_segments = reds
75+
.iter()
76+
.chain([reds[0]].iter())
77+
.tuple_windows()
78+
.map(|(a, b)| Rectangle::from(a, b))
79+
.collect::<Vec<_>>();
80+
Self::rectangles(reds)
81+
.filter(|r| !border_segments.iter().any(|bs| r.intersect(bs)))
82+
.map(|r| r.area())
83+
.max()
84+
.unwrap()
85+
}
86+
87+
fn samples(&self) {
88+
aoc::puzzle_samples! {
89+
self, part_1, TEST, 50,
90+
self, part_2, TEST, 24
91+
};
92+
}
93+
}
94+
95+
fn main() {
96+
AoC2025_09 {}.run(std::env::args());
97+
}
98+
99+
const TEST: &str = "\
100+
7,1
101+
11,1
102+
11,7
103+
9,7
104+
9,5
105+
2,5
106+
2,3
107+
7,3
108+
";
109+
110+
#[cfg(test)]
111+
mod tests {
112+
use super::*;
113+
114+
#[test]
115+
pub fn samples() {
116+
AoC2025_09 {}.samples();
117+
}
118+
}

src/main/rust/Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)