Skip to content

Commit 77c64fc

Browse files
committed
Year 2025 Day 9
1 parent d32dd68 commit 77c64fc

File tree

7 files changed

+132
-4
lines changed

7 files changed

+132
-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) | 668 |
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: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
let shrink_x = shrink(tiles, 0);
35+
let shrink_y = shrink(tiles, 1);
36+
let shrunk: Vec<_> = tiles.iter().map(|&[x, y]| (shrink_x[&x], shrink_y[&y])).collect();
37+
38+
let mut area = 0;
39+
let mut todo = VecDeque::from([ORIGIN]);
40+
let mut grid = Grid::new(shrink_x.len() as i32, shrink_y.len() as i32, UNKNOWN);
41+
42+
for i in 0..size {
43+
let (x1, y1, x2, y2) = minmax(shrunk[i], shrunk[(i + 1) % size]);
44+
45+
for x in x1..x2 + 1 {
46+
for y in y1..y2 + 1 {
47+
grid[Point::new(x, y)] = INSIDE;
48+
}
49+
}
50+
}
51+
52+
while let Some(point) = todo.pop_front() {
53+
for next in ORTHOGONAL.map(|o| point + o) {
54+
if grid.contains(next) && grid[next] == UNKNOWN {
55+
grid[next] = OUTSIDE;
56+
todo.push_back(next);
57+
}
58+
}
59+
}
60+
61+
for y in 1..grid.height {
62+
for x in 1..grid.width {
63+
let point = Point::new(x, y);
64+
let value = i64::from(grid[point] != OUTSIDE);
65+
grid[point] = value + grid[point + UP] + grid[point + LEFT] - grid[point + UP + LEFT];
66+
}
67+
}
68+
69+
for i in 0..size {
70+
for j in i + 1..size {
71+
let (x1, y1, x2, y2) = minmax(shrunk[i], shrunk[j]);
72+
73+
let expected = (x2 - x1 + 1) as i64 * (y2 - y1 + 1) as i64;
74+
let actual = grid[Point::new(x2, y2)]
75+
- grid[Point::new(x1 - 1, y2)]
76+
- grid[Point::new(x2, y1 - 1)]
77+
+ grid[Point::new(x1 - 1, y1 - 1)];
78+
79+
if expected == actual {
80+
let [x1, y1] = tiles[i];
81+
let [x2, y2] = tiles[j];
82+
let dx = x1.abs_diff(x2) + 1;
83+
let dy = y1.abs_diff(y2) + 1;
84+
area = area.max(dx * dy);
85+
}
86+
}
87+
}
88+
89+
area
90+
}
91+
92+
fn shrink(tiles: &[Tile], index: usize) -> FastMap<u64, i32> {
93+
let mut ns: Vec<_> = tiles.iter().map(|tile| tile[index]).collect();
94+
ns.push(0);
95+
ns.push(u64::MAX);
96+
ns.sort_unstable();
97+
ns.dedup();
98+
ns.iter().enumerate().map(|(i, &n)| (n, i as i32)).collect()
99+
}
100+
101+
#[inline]
102+
fn minmax((x1, y1): (i32, i32), (x2, y2): (i32, i32)) -> (i32, i32, i32, i32) {
103+
(x1.min(x2), y1.min(y2), x1.max(x2), y1.max(y2))
104+
}

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)