Skip to content

Commit 5697bee

Browse files
committed
Add day 22 solution
1 parent e17cfa8 commit 5697bee

File tree

2 files changed

+128
-1
lines changed

2 files changed

+128
-1
lines changed

src/day22.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#[allow(unused_imports)]
2+
use super::prelude::*;
3+
type Input = Vec<((usize, usize, usize), (usize, usize, usize))>;
4+
5+
pub fn input_generator(input: &str) -> Input {
6+
input
7+
.lines()
8+
.map(|line| {
9+
let (x1, y1, z1, x2, y2, z2) = line
10+
.split(&[',', '~'][..])
11+
.map(|n| n.parse().unwrap())
12+
.collect_tuple()
13+
.unwrap();
14+
((x1, y1, z1), (x2, y2, z2))
15+
})
16+
.collect()
17+
}
18+
19+
pub fn part1(input: &Input) -> usize {
20+
let mut input = input.clone();
21+
input.sort_by_key(|&((x, y, z), _)| (z, x, y));
22+
23+
let mut maxx = 0;
24+
let mut maxy = 0;
25+
26+
for &((x1, y1, _), (x2, y2, _)) in &input {
27+
maxx = max(maxx, x1);
28+
maxy = max(maxy, y1);
29+
maxx = max(maxx, x2);
30+
maxy = max(maxy, y2);
31+
}
32+
33+
let mut supported_by = FxHashSet::default();
34+
35+
let mut supporting = vec![false; input.len()];
36+
let mut last = vec![(usize::MAX, 0); (maxx + 1) * (maxy + 1)];
37+
38+
for (i, &((x1, y1, z1), (x2, y2, z2))) in input.iter().enumerate() {
39+
let mut z_target = 0;
40+
for x in x1..x2 + 1 {
41+
for y in y1..y2 + 1 {
42+
z_target = max(z_target, last[y * (maxx + 1) + x].1)
43+
}
44+
}
45+
46+
for x in x1..x2 + 1 {
47+
for y in y1..y2 + 1 {
48+
let (s, l) = last[y * (maxx + 1) + x];
49+
if l == z_target && s != usize::MAX {
50+
supported_by.insert(s);
51+
}
52+
last[y * (maxx + 1) + x] = (i, z_target + z2 - z1 + 1);
53+
}
54+
}
55+
if supported_by.len() == 1 {
56+
supporting[*supported_by.iter().next().unwrap()] = true;
57+
}
58+
supported_by.clear();
59+
}
60+
61+
supporting.iter().filter(|&&sup| !sup).count()
62+
}
63+
64+
pub fn part2(input: &Input) -> usize {
65+
let mut input = input.clone();
66+
input.sort_by_key(|&((x, y, z), _)| (z, x, y));
67+
68+
let mut maxx = 0;
69+
let mut maxy = 0;
70+
71+
for &((x1, y1, _), (x2, y2, _)) in &input {
72+
maxx = max(maxx, x1);
73+
maxy = max(maxy, y1);
74+
maxx = max(maxx, x2);
75+
maxy = max(maxy, y2);
76+
}
77+
78+
let mut under = vec![FxHashSet::default(); input.len()];
79+
let mut over = vec![FxHashSet::default(); input.len()];
80+
let mut last = vec![(usize::MAX, 0); (maxx + 1) * (maxy + 1)];
81+
82+
for (i, &((x1, y1, z1), (x2, y2, z2))) in input.iter().enumerate() {
83+
let mut z_target = 0;
84+
for x in x1..x2 + 1 {
85+
for y in y1..y2 + 1 {
86+
z_target = max(z_target, last[y * (maxx + 1) + x].1)
87+
}
88+
}
89+
90+
for x in x1..x2 + 1 {
91+
for y in y1..y2 + 1 {
92+
let (s, l) = last[y * (maxx + 1) + x];
93+
if l == z_target && s != usize::MAX {
94+
over[s].insert(i);
95+
under[i].insert(s);
96+
}
97+
last[y * (maxx + 1) + x] = (i, z_target + z2 - z1 + 1);
98+
}
99+
}
100+
}
101+
102+
let mut sum = 0;
103+
let mut queue = VecDeque::new();
104+
let mut seen = FxHashSet::default();
105+
for i in 0..input.len() {
106+
queue.extend(over[i].iter().copied());
107+
seen.clear();
108+
seen.insert(i);
109+
110+
'outer: while let Some(brick) = queue.pop_front() {
111+
if seen.contains(&brick) {
112+
continue;
113+
}
114+
115+
for u in &under[brick] {
116+
if !seen.contains(u) {
117+
continue 'outer;
118+
}
119+
}
120+
121+
sum += 1;
122+
seen.insert(brick);
123+
queue.extend(over[brick].iter().copied());
124+
}
125+
}
126+
sum
127+
}

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ aoc_helper::main!(2023 =>
2020
day19,
2121
day20,
2222
day21,
23-
// day22,
23+
day22,
2424
// day23,
2525
// day24,
2626
// day25,

0 commit comments

Comments
 (0)