Skip to content

Commit 791bcf3

Browse files
committed
[2025] Solution for Day 9
1 parent 8e067eb commit 791bcf3

File tree

5 files changed

+134
-1
lines changed

5 files changed

+134
-1
lines changed

2025/src/bin/day09.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use aoc2025::days::day09::{part1, part2};
2+
use std::env;
3+
use std::fs;
4+
use std::process;
5+
6+
fn main() {
7+
let args: Vec<String> = env::args().collect();
8+
if args.len() < 3 {
9+
println!("Missing required arguments");
10+
process::exit(1);
11+
}
12+
13+
let contents = fs::read_to_string(&args[1]).expect("Something went wrong");
14+
println!("Part 1: {}", part1(&contents));
15+
println!("Part 2: {}", part2(&contents));
16+
}

2025/src/days.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ pub mod day05;
66
pub mod day06;
77
pub mod day07;
88
pub mod day08;
9+
pub mod day09;

2025/src/days/day09.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
struct Point {
2+
x: i64,
3+
y: i64,
4+
}
5+
6+
impl Point {
7+
fn new(x: i64, y: i64) -> Self {
8+
Point { x, y }
9+
}
10+
11+
fn area(&self, other: &Point) -> i64 {
12+
((self.x - other.x).abs() + 1) * ((self.y - other.y).abs() + 1)
13+
}
14+
}
15+
16+
pub fn part1(contents: &str) -> i64 {
17+
let points = parse_input(contents);
18+
let mut max_area = 0;
19+
for (i, p1) in points.iter().enumerate() {
20+
for p2 in &points[i + 1..] {
21+
let area = p1.area(p2);
22+
if area > max_area {
23+
max_area = area;
24+
}
25+
}
26+
}
27+
max_area
28+
}
29+
30+
pub fn part2(contents: &str) -> i64 {
31+
let points = parse_input(contents);
32+
let mut max_area = 0;
33+
for (i, p1) in points.iter().enumerate() {
34+
for p2 in &points[i + 1..] {
35+
let area = p1.area(p2);
36+
if area > max_area && is_interior(p1, p2, &points) {
37+
max_area = area;
38+
}
39+
}
40+
}
41+
max_area
42+
}
43+
44+
fn parse_input(input: &str) -> Vec<Point> {
45+
input
46+
.lines()
47+
.map(|line| {
48+
let coords: Vec<i64> = line.split(',').map(|s| s.parse().unwrap()).collect();
49+
Point::new(coords[0], coords[1])
50+
})
51+
.collect()
52+
}
53+
54+
fn is_interior(p1: &Point, p2: &Point, points: &[Point]) -> bool {
55+
let max_x = if p1.x > p2.x { p1.x } else { p2.x };
56+
let min_x = if p1.x < p2.x { p1.x } else { p2.x };
57+
let max_y = if p1.y > p2.y { p1.y } else { p2.y };
58+
let min_y = if p1.y < p2.y { p1.y } else { p2.y };
59+
for (i, p) in points.iter().enumerate() {
60+
if (p.x > min_x && p.x < max_x) && (p.y > min_y && p.y < max_y) {
61+
// Fully inside
62+
return false;
63+
} else {
64+
let next = &points[(i + 1) % points.len()];
65+
let min_line_x = if p.x < next.x { p.x } else { next.x };
66+
let max_line_x = if p.x > next.x { p.x } else { next.x };
67+
let min_line_y = if p.y < next.y { p.y } else { next.y };
68+
let max_line_y = if p.y > next.y { p.y } else { next.y };
69+
if (min_line_x <= min_x
70+
&& max_line_x >= max_x
71+
&& min_line_y > min_y
72+
&& max_line_y < max_y)
73+
|| (min_line_y <= min_y
74+
&& max_line_y >= max_y
75+
&& min_line_x > min_x
76+
&& max_line_x < max_x)
77+
{
78+
// Line crosses rectangle
79+
return false;
80+
}
81+
}
82+
}
83+
true
84+
}
85+
86+
#[cfg(test)]
87+
mod tests {
88+
use super::*;
89+
90+
#[test]
91+
fn test_part1() {
92+
let input = vec!["7,1", "11,1", "11,7", "9,7", "9,5", "2,5", "2,3", "7,3"];
93+
94+
assert_eq!(part1(&input.join("\n")), 50);
95+
}
96+
97+
#[test]
98+
fn test_part2() {
99+
let input = vec!["7,1", "11,1", "11,7", "9,7", "9,5", "2,5", "2,3", "7,3"];
100+
101+
assert_eq!(part2(&input.join("\n")), 24);
102+
}
103+
}

2025/tests/day09.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use aoc2025::days::day09::{part1, part2};
2+
3+
#[test]
4+
fn test_part1() {
5+
let content = std::include_str!("../../private/inputs/2025/day09.txt");
6+
assert_eq!(part1(&content), 4749672288);
7+
}
8+
9+
#[test]
10+
fn test_part2() {
11+
let content = std::include_str!("../../private/inputs/2025/day09.txt");
12+
assert_eq!(part2(&content), 1479665889);
13+
}

private

0 commit comments

Comments
 (0)