Skip to content

Commit 5ec509f

Browse files
committed
2025: day 9
1 parent 72925ad commit 5ec509f

File tree

7 files changed

+146
-10
lines changed

7 files changed

+146
-10
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# [Advent of Code](https://adventofcode.com) in Rust 🦀
22

3-
![Stars: 516](https://img.shields.io/badge/Stars-516⭐-blue)
4-
![Rust: 258](https://img.shields.io/badge/Rust-258-cyan?logo=Rust)
3+
![Stars: 518](https://img.shields.io/badge/Stars-518⭐-blue)
4+
![Rust: 259](https://img.shields.io/badge/Rust-259-cyan?logo=Rust)
55
![Python: 127](https://img.shields.io/badge/Python-127-cyan?logo=Python)
66

77
<img src="./scripts/assets/christmas_ferris_2015_2024.png" alt="Christmas Ferris" width="164" />
@@ -10,7 +10,7 @@
1010

1111
Made for fun 😎 and to practice Rust. Many thanks to [Eric Wastl](https://twitter.com/ericwastl).
1212

13-
## 2025 (current event) ([Calendar](https://adventofcode.com/2025)) ([Solutions](src/year2025/)) : 16
13+
## 2025 (current event) ([Calendar](https://adventofcode.com/2025)) ([Solutions](src/year2025/)) : 18
1414

1515
Puzzle | Stars | Languages
1616
----------------------------------------------------------------- | ----- | -----------
@@ -22,12 +22,13 @@ Puzzle | Stars | Lang
2222
[Day 6: Trash Compactor](https://adventofcode.com/2025/day/6) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day6/day6.rs) [![Rust](./scripts/assets/rust.png)](src/year2025/day6/day6_declarative.rs) [![Python](./scripts/assets/python.png)](src/year2025/day6/day6.py)
2323
[Day 7: Laboratories](https://adventofcode.com/2025/day/7) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day7/day7.rs) [![Go](./scripts/assets/go.png)](src/year2025/day7/day7.go) [🎁](src/year2025/day7/README.md)
2424
[Day 8: Playground](https://adventofcode.com/2025/day/8) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day8/day8.rs)
25+
[Day 9: Movie Theater](https://adventofcode.com/2025/day/9) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day9/day9.rs)
2526

2627
## All years
2728

2829
Calendar | Solutions | Stars | Rust | Python | 🎁
2930
-------- | --------- | ----- | ---- | ------ | --
30-
[Advent of Code 2025](https://adventofcode.com/2025) | [Solutions](src/year2025/README.md) | 16⭐ | 8 | 5 | 1
31+
[Advent of Code 2025](https://adventofcode.com/2025) | [Solutions](src/year2025/README.md) | 18⭐ | 9 | 5 | 1
3132
[Advent of Code 2024](https://adventofcode.com/2024) | [Solutions](src/year2024/README.md) | 50⭐ | 25 | 11 | 3
3233
[Advent of Code 2023](https://adventofcode.com/2023) | [Solutions](src/year2023/README.md) | 50⭐ | 25 | 10 | 2
3334
[Advent of Code 2022](https://adventofcode.com/2022) | [Solutions](src/year2022/README.md) | 50⭐ | 25 | 18 | 1

scripts/aoc.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,14 @@ def aoc_readme(ctx: click.Context):
269269

270270

271271
@aoc.command(name="inputs")
272+
@click.option("--ok", is_flag=True, help="Only inputs with solution")
272273
@click.pass_context
273-
def aoc_inputs(ctx: click.Context):
274+
def aoc_inputs(ctx: click.Context, ok: bool):
274275
"""
275276
Show the number of available inputs.
276277
"""
277-
ctx.obj.pass_thru("inputs.py", [])
278+
opts = ["--ok"] if ok else []
279+
ctx.obj.pass_thru("inputs.py", opts)
278280

279281

280282
@aoc.command(name="scores")

scripts/inputs.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22

3+
import argparse
34
import time
45
import typing as t
56
from collections import Counter
@@ -79,6 +80,11 @@ def transpose(m):
7980
return t
8081

8182

83+
parser = argparse.ArgumentParser()
84+
parser.add_argument("--ok", action="store_true", help="Only inputs with solution")
85+
args = parser.parse_args()
86+
87+
8288
datadir = Path(__file__).parent.parent / "data"
8389

8490
data = []
@@ -106,6 +112,10 @@ def transpose(m):
106112
# continue
107113
if f.is_dir():
108114
f = f / f"{year}" / f"{day}.in"
115+
116+
if args.ok and not f.with_suffix(".ok").is_file():
117+
continue
118+
109119
if f.is_file():
110120
inputs.update([f.read_text().strip()])
111121

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,5 +127,5 @@ make_year!(year2024
127127
);
128128

129129
make_year!(year2025
130-
day1,day2,day3,day4,day5,day6,day7,day8
130+
day1,day2,day3,day4,day5,day6,day7,day8,day9
131131
);

src/year2025/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Advent of Code in Rust 🦀
22

33
![AoC2025](https://img.shields.io/badge/Advent_of_Code-2025-8A2BE2)
4-
![Stars: 16](https://img.shields.io/badge/Stars-16⭐-blue)
5-
![Rust: 9](https://img.shields.io/badge/Rust-9-cyan?logo=Rust)
4+
![Stars: 18](https://img.shields.io/badge/Stars-18⭐-blue)
5+
![Rust: 10](https://img.shields.io/badge/Rust-10-cyan?logo=Rust)
66
![Python: 5](https://img.shields.io/badge/Python-5-cyan?logo=Python)
77

8-
## 2025 ([Calendar](https://adventofcode.com/2025)) ([Solutions](./)) : 16
8+
## 2025 ([Calendar](https://adventofcode.com/2025)) ([Solutions](./)) : 18
99

1010
Puzzle | Stars | Languages
1111
----------------------------------------------------------------- | ----- | -----------
@@ -17,3 +17,4 @@ Puzzle | Stars | Lang
1717
[Day 6: Trash Compactor](https://adventofcode.com/2025/day/6) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day6/day6.rs) [![Rust](../../scripts/assets/rust.png)](day6/day6_declarative.rs) [![Python](../../scripts/assets/python.png)](day6/day6.py)
1818
[Day 7: Laboratories](https://adventofcode.com/2025/day/7) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day7/day7.rs) [![Go](../../scripts/assets/go.png)](day7/day7.go) [🎁](day7/README.md)
1919
[Day 8: Playground](https://adventofcode.com/2025/day/8) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day8/day8.rs)
20+
[Day 9: Movie Theater](https://adventofcode.com/2025/day/9) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day9/day9.rs)

src/year2025/day9/day9.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//! [Day 9: Movie Theater](https://adventofcode.com/2025/day/9)
2+
3+
// Nota: not a good solution 😡 But it solves the puzzle...
4+
5+
use geo::algorithm::contains::Contains;
6+
use geo::{Point, Polygon, Rect};
7+
use itertools::Itertools;
8+
9+
struct Puzzle {
10+
points: Vec<Point>,
11+
}
12+
13+
impl Puzzle {
14+
/// Initialize from the puzzle input.
15+
fn new(data: &str) -> Self {
16+
Self {
17+
points: data
18+
.lines()
19+
.map(|line| {
20+
let (x, y) = line
21+
.split(',')
22+
.map(|x| x.parse::<f64>().unwrap())
23+
.collect_tuple()
24+
.unwrap();
25+
26+
Point::new(x, y)
27+
})
28+
.collect(),
29+
}
30+
}
31+
32+
/// Solve part one.
33+
fn part1(&self) -> f64 {
34+
let mut max_area = 0.;
35+
36+
for (i, p1) in self.points.iter().enumerate() {
37+
for (j, p2) in self.points.iter().enumerate() {
38+
if i > j {
39+
let xmin = p1.x().min(p2.x());
40+
let xmax = p1.x().max(p2.x());
41+
let ymin = p1.y().min(p2.y());
42+
let ymax = p1.y().max(p2.y());
43+
44+
let area = (xmax + 1. - xmin) * (ymax + 1. - ymin);
45+
if area > max_area {
46+
max_area = area;
47+
}
48+
}
49+
}
50+
}
51+
52+
max_area
53+
}
54+
55+
/// Solve part two.
56+
fn part2(&self) -> f64 {
57+
let poly = Polygon::new(self.points.clone().into(), vec![]);
58+
59+
let mut max_area = 0.;
60+
61+
for (i, p1) in self.points.iter().enumerate() {
62+
for (j, p2) in self.points.iter().enumerate() {
63+
if i > j {
64+
let xmin = p1.x().min(p2.x());
65+
let xmax = p1.x().max(p2.x());
66+
let ymin = p1.y().min(p2.y());
67+
let ymax = p1.y().max(p2.y());
68+
69+
let rect = Rect::new((xmin, ymin), (xmax, ymax));
70+
71+
if poly.contains(&rect) {
72+
let area = (xmax + 1. - xmin) * (ymax + 1. - ymin);
73+
if area > max_area {
74+
max_area = area;
75+
}
76+
}
77+
}
78+
}
79+
}
80+
81+
max_area
82+
}
83+
}
84+
85+
/// # Panics
86+
#[must_use]
87+
pub fn solve(data: &str) -> (f64, f64) {
88+
let puzzle = Puzzle::new(data);
89+
(puzzle.part1(), puzzle.part2())
90+
}
91+
92+
pub fn main() {
93+
let args = aoc::parse_args();
94+
args.run(solve);
95+
}
96+
97+
#[cfg(test)]
98+
mod test {
99+
use super::*;
100+
101+
const TEST_INPUT: &str = include_str!("test.txt");
102+
103+
#[test]
104+
fn part1() {
105+
let puzzle = Puzzle::new(TEST_INPUT);
106+
assert_eq!(puzzle.part1(), 50.);
107+
}
108+
109+
#[test]
110+
fn part2() {
111+
let puzzle = Puzzle::new(TEST_INPUT);
112+
assert_eq!(puzzle.part2(), 24.);
113+
}
114+
}

src/year2025/day9/test.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
7,1
2+
11,1
3+
11,7
4+
9,7
5+
9,5
6+
2,5
7+
2,3
8+
7,3

0 commit comments

Comments
 (0)