-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday18.rs
69 lines (59 loc) · 2 KB
/
day18.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#[allow(unused_imports)]
use super::prelude::*;
type Input = Vec<(usize, usize, usize)>;
pub fn input_generator(input: &str) -> Input {
input
.lines()
.map(|line| {
let (x, y, z) = line.split(',').collect_tuple().expect("Invalid input");
let x = x.parse().expect("Invalid input");
let y = y.parse().expect("Invalid input");
let z = z.parse().expect("Invalid input");
(x, y, z)
})
.collect()
}
fn solve(input: &Input, count_sides: impl Fn(usize, usize, usize) -> usize) -> usize {
input.iter().map(|&(x, y, z)| count_sides(x, y, z)).sum()
}
fn lens(input: &Input) -> (usize, usize, usize) {
input
.iter()
.fold((0, 0, 0), |(lenx, leny, lenz), &(x, y, z)| {
(max(lenx, x + 1), max(leny, y + 1), max(lenz, z + 1))
})
}
pub fn part1(input: &Input) -> usize {
let (lenx, leny, lenz) = lens(input);
let mut set = Grid3D::with_dimensions(lenx + 2, leny + 2, lenz + 2).into_set();
for &(x, y, z) in input {
set.insert((x + 1, y + 1, z + 1));
}
solve(input, |x, y, z| {
set.plus_neighbours((x + 1, y + 1, z + 1))
.filter(|&p| !set.contains(p))
.count()
})
}
pub fn part2(input: &Input) -> usize {
let (lenx, leny, lenz) = lens(input);
let mut set = Grid3D::with_dimensions(lenx + 2, leny + 2, lenz + 2).into_set();
for &(x, y, z) in input {
set.insert((x + 1, y + 1, z + 1));
}
let mut wrapper = Grid3D::with_dimensions(lenx + 2, leny + 2, lenz + 2).into_set();
let mut stack = vec![(0, 0, 0)];
while let Some((x, y, z)) = stack.pop() {
for (x, y, z) in set.plus_neighbours((x, y, z)) {
if !set.contains((x, y, z)) && wrapper.insert((x, y, z)) {
stack.push((x, y, z))
}
}
}
solve(input, |x, y, z| {
wrapper
.plus_neighbours((x + 1, y + 1, z + 1))
.filter(|&p| wrapper.contains(p))
.count()
})
}