Day 18, part 1

This commit is contained in:
jazzpi 2022-12-20 16:44:34 +01:00
parent 22d9f7c42a
commit ff8870eb3e
3 changed files with 131 additions and 0 deletions

7
src/bin/d18p1.rs Normal file
View File

@ -0,0 +1,7 @@
use aoc22::{day18, util};
pub fn main() {
let droplet = day18::parse_droplet(&util::parse_input());
println!("Surface area: {}", day18::surface_area(&droplet));
}

123
src/day18.rs Normal file
View File

@ -0,0 +1,123 @@
use itertools::Itertools;
pub fn parse_droplet(input: &String) -> Vec<Vec<Vec<bool>>> {
let mut cubes: Vec<(usize, usize, usize)> = Vec::new();
for line in input.lines() {
if line.is_empty() {
break;
}
let mut sp = line.split(',');
cubes.push((
sp.next().unwrap().parse().unwrap(),
sp.next().unwrap().parse().unwrap(),
sp.next().unwrap().parse().unwrap(),
));
}
let (x_min, x_max) = cubes.iter().map(|c| c.0).minmax().into_option().unwrap();
let (y_min, y_max) = cubes.iter().map(|c| c.1).minmax().into_option().unwrap();
let (z_min, z_max) = cubes.iter().map(|c| c.2).minmax().into_option().unwrap();
let x_len = x_max - x_min + 1;
let y_len = y_max - y_min + 1;
let z_len = z_max - z_min + 1;
let mut result = vec![vec![vec![false; z_len]; y_len]; x_len];
for (x, y, z) in cubes {
result[x - x_min][y - y_min][z - z_min] = true;
}
result
}
pub fn surface_area(droplet: &Vec<Vec<Vec<bool>>>) -> usize {
let x_len = droplet.len();
assert!(x_len > 0);
let y_len = droplet[0].len();
assert!(y_len > 0);
let z_len = droplet[0][0].len();
assert!(z_len > 0);
let up = (0..x_len)
.flat_map(|x| {
(0..y_len)
.map(move |y| (x, y, (0..z_len).collect()))
.collect_vec()
})
.collect();
let down = (0..x_len)
.flat_map(|x| {
(0..y_len)
.map(move |y| (x, y, (0..z_len).rev().collect()))
.collect_vec()
})
.collect();
let left = (0..x_len)
.flat_map(|x| {
(0..z_len)
.map(move |z| (x, z, (0..y_len).collect()))
.collect_vec()
})
.collect();
let right = (0..x_len)
.flat_map(|x| {
(0..z_len)
.map(move |z| (x, z, (0..y_len).rev().collect()))
.collect_vec()
})
.collect();
let fore = (0..y_len)
.flat_map(|y| {
(0..z_len)
.map(move |z| (y, z, (0..x_len).collect()))
.collect_vec()
})
.collect();
let back = (0..y_len)
.flat_map(|y| {
(0..z_len)
.map(move |z| (y, z, (0..x_len).rev().collect()))
.collect_vec()
})
.collect();
let mut result = 0;
result += surface_area_dir(droplet, &up, ArgOrder::XYZ);
result += surface_area_dir(droplet, &down, ArgOrder::XYZ);
result += surface_area_dir(droplet, &left, ArgOrder::XZY);
result += surface_area_dir(droplet, &right, ArgOrder::XZY);
result += surface_area_dir(droplet, &fore, ArgOrder::YZX);
result += surface_area_dir(droplet, &back, ArgOrder::YZX);
result
}
enum ArgOrder {
XYZ,
XZY,
YZX,
}
fn surface_area_dir(
droplet: &Vec<Vec<Vec<bool>>>,
lines: &Vec<(usize, usize, Vec<usize>)>,
order: ArgOrder,
) -> usize {
let mut result = 0;
for (a, b, c_range) in lines {
let mut last_empty = true;
for c in c_range {
let occupied = match order {
ArgOrder::XYZ => droplet[*a][*b][*c],
ArgOrder::XZY => droplet[*a][*c][*b],
ArgOrder::YZX => droplet[*c][*a][*b],
};
if last_empty && occupied {
result += 1;
}
last_empty = !occupied;
}
}
result
}

View File

@ -7,6 +7,7 @@ pub mod day14;
pub mod day15;
pub mod day16;
pub mod day17;
pub mod day18;
pub mod day2;
pub mod day3;
pub mod day4;