Skip to content

Commit d3830ce

Browse files
committed
Year 2025 Day 9
1 parent d32dd68 commit d3830ce

File tree

7 files changed

+138
-4
lines changed

7 files changed

+138
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro
8585
| 6 | [Trash Compactor](https://adventofcode.com/2025/day/6) | [Source](src/year2025/day06.rs) | 20 |
8686
| 7 | [Laboratories](https://adventofcode.com/2025/day/7) | [Source](src/year2025/day07.rs) | 5 |
8787
| 8 | [Playground](https://adventofcode.com/2025/day/8) | [Source](src/year2025/day08.rs) | 527 |
88+
| 9 | [Movie Theater](https://adventofcode.com/2025/day/9) | [Source](src/year2025/day09.rs) | 683 |
8889

8990
## 2024
9091

benches/benchmark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,5 @@ benchmark!(year2024
9595
);
9696

9797
benchmark!(year2025
98-
day01, day02, day03, day04, day05, day06, day07, day08
98+
day01, day02, day03, day04, day05, day06, day07, day08, day09
9999
);

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,5 @@ library!(year2024 "Locate the Chief Historian in time for the big Christmas slei
7474
);
7575

7676
library!(year2025 "Finish the North Pole decorations in time for Christmas."
77-
day01, day02, day03, day04, day05, day06, day07, day08
77+
day01, day02, day03, day04, day05, day06, day07, day08, day09
7878
);

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,5 @@ run!(year2024
141141
);
142142

143143
run!(year2025
144-
day01, day02, day03, day04, day05, day06, day07, day08
144+
day01, day02, day03, day04, day05, day06, day07, day08, day09
145145
);

src/year2025/day09.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use crate::util::grid::*;
2+
use crate::util::hash::*;
3+
use crate::util::iter::*;
4+
use crate::util::parse::*;
5+
use crate::util::point::*;
6+
use std::collections::VecDeque;
7+
8+
const OUTSIDE: i64 = 0;
9+
const INSIDE: i64 = 1;
10+
const UNKNOWN: i64 = 2;
11+
12+
type Tile = [u64; 2];
13+
14+
pub fn parse(input: &str) -> Vec<Tile> {
15+
input.iter_unsigned::<u64>().chunk::<2>().collect()
16+
}
17+
18+
pub fn part1(tiles: &[Tile]) -> u64 {
19+
let mut area = 0;
20+
21+
for (i, &[x1, y1]) in tiles.iter().enumerate() {
22+
for &[x2, y2] in tiles.iter().skip(i + 1) {
23+
let dx = x1.abs_diff(x2) + 1;
24+
let dy = y1.abs_diff(y2) + 1;
25+
area = area.max(dx * dy);
26+
}
27+
}
28+
29+
area
30+
}
31+
32+
pub fn part2(tiles: &[Tile]) -> u64 {
33+
let size = tiles.len();
34+
35+
let mut xs: Vec<_> = tiles.iter().map(|&[x, _]| x).collect();
36+
xs.push(0);
37+
xs.push(u64::MAX);
38+
xs.sort_unstable();
39+
xs.dedup();
40+
41+
let mut ys: Vec<_> = tiles.iter().map(|&[_, y]| y).collect();
42+
ys.push(0);
43+
ys.push(u64::MAX);
44+
ys.sort_unstable();
45+
ys.dedup();
46+
47+
let shrink_x: FastMap<_, _> = xs.iter().enumerate().map(|(i, &x)| (x, i as i32)).collect();
48+
let shrink_y: FastMap<_, _> = ys.iter().enumerate().map(|(i, &y)| (y, i as i32)).collect();
49+
let shrunk: Vec<_> = tiles.iter().map(|&[x, y]| (shrink_x[&x], shrink_y[&y])).collect();
50+
51+
let mut area = 0;
52+
let mut todo = VecDeque::from([ORIGIN]);
53+
let mut grid = Grid::new(shrink_x.len() as i32, shrink_y.len() as i32, UNKNOWN);
54+
55+
for i in 0..size {
56+
let (x1, y1) = shrunk[i];
57+
let (x2, y2) = shrunk[(i + 1) % size];
58+
59+
for x in x1.min(x2)..=x1.max(x2) {
60+
for y in y1.min(y2)..=y1.max(y2) {
61+
grid[Point::new(x, y)] = INSIDE;
62+
}
63+
}
64+
}
65+
66+
while let Some(point) = todo.pop_front() {
67+
for next in ORTHOGONAL.map(|o| point + o) {
68+
if grid.contains(next) && grid[next] == UNKNOWN {
69+
grid[next] = OUTSIDE;
70+
todo.push_back(next);
71+
}
72+
}
73+
}
74+
75+
for y in 1..grid.height {
76+
for x in 1..grid.width {
77+
let point = Point::new(x, y);
78+
let value = i64::from(grid[point] != OUTSIDE);
79+
grid[point] = value + grid[point + UP] + grid[point + LEFT] - grid[point + UP + LEFT];
80+
}
81+
}
82+
83+
for i in 0..size {
84+
for j in i + 1..size {
85+
let (x1, y1) = shrunk[i];
86+
let (x2, y2) = shrunk[j];
87+
88+
let x3 = x1.min(x2);
89+
let x4 = x1.max(x2);
90+
let y3 = y1.min(y2);
91+
let y4 = y1.max(y2);
92+
93+
let expected = (x4 - x3 + 1) as i64 * (y4 - y3 + 1) as i64;
94+
let actual = grid[Point::new(x4, y4)]
95+
- grid[Point::new(x3 - 1, y4)]
96+
- grid[Point::new(x4, y3 - 1)]
97+
+ grid[Point::new(x3 - 1, y3 - 1)];
98+
99+
if expected == actual {
100+
let [x1, y1] = tiles[i];
101+
let [x2, y2] = tiles[j];
102+
let dx = x1.abs_diff(x2) + 1;
103+
let dy = y1.abs_diff(y2) + 1;
104+
area = area.max(dx * dy);
105+
}
106+
}
107+
}
108+
109+
area
110+
}

tests/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,5 @@ test!(year2024
8787
);
8888

8989
test!(year2025
90-
day01, day02, day03, day04, day05, day06, day07, day08
90+
day01, day02, day03, day04, day05, day06, day07, day08, day09
9191
);

tests/year2025/day09.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use aoc::year2025::day09::*;
2+
3+
const EXAMPLE: &str = "\
4+
7,1
5+
11,1
6+
11,7
7+
9,7
8+
9,5
9+
2,5
10+
2,3
11+
7,3";
12+
13+
#[test]
14+
fn part1_test() {
15+
let input = parse(EXAMPLE);
16+
assert_eq!(part1(&input), 50);
17+
}
18+
19+
#[test]
20+
fn part2_test() {
21+
let input = parse(EXAMPLE);
22+
assert_eq!(part2(&input), 24);
23+
}

0 commit comments

Comments
 (0)