This commit is contained in:
Dory 2024-06-17 22:30:37 -07:00
parent 5d522dc0f6
commit 976cb3651c
3 changed files with 170 additions and 14 deletions

93
day18/src/main.array3d.rs Normal file
View File

@ -0,0 +1,93 @@
use std::io;
use std::env;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::collections::HashSet;
use std::collections::VecDeque;
mod rustsux {
use std::fmt;
pub struct Array3D<T: Copy> {
backing_vec: Vec<T>,
pub d1: usize, pub d2: usize, pub d3: usize,
}
impl<T: Copy> Array3D<T> {
pub fn new(d1: usize, d2: usize, d3: usize, init: T) -> Array3D<T> {
Array3D {
backing_vec: vec![init; d1 * d2 * d3],
d1: d1, d2: d2, d3: d3,
}
}
pub fn get(&self, x: usize, y: usize, z: usize) -> T {
self.backing_vec[x*self.d2*self.d3 + y*self.d3 + z]
}
pub fn set(&mut self, x: usize, y: usize, z: usize, val: T) {
self.backing_vec[x*self.d2*self.d3 + y*self.d3 + z] = val;
}
}
impl<T: fmt::Display + Copy> fmt::Debug for Array3D<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for x in 0..self.d1 {
write!(f, "")?;
for y in 0..self.d2 {
let row_start = x*self.d2*self.d3 + y*self.d3;
let row_end = x*self.d2*self.d3 + (y + 1)*self.d3;
for z in row_start..row_end {
write!(f, "{}", self.backing_vec[z])?;
}
write!(f, " ")?;
}
writeln!(f, "")?;
}
Ok(())
}
}
}
fn floodfill_surface<T: Copy>(map: rustsux::Array3D<T>, block_sym: T) -> usize {
// TODO: start from arbitrary spot instead of 0, 0, 0
let mut queue = VecDeque::new();
queue.push_back((0, 0, 0));
while let Some((x, y, z)) = queue.pop_front() {
println!("{} {} {}", x, y, z);
}
0
}
fn main() -> io::Result<()> {
let input_fname = env::args().nth(1).expect("need input file");
let lines = BufReader::new(File::open(input_fname)?).lines();
let mut cubes: HashSet<(usize, usize, usize)> = HashSet::new();
let (mut max_x, mut max_y, mut max_z) = (0, 0, 0);
for line in lines.flatten() {
let mut split = line.split(',');
// +1 so that we have a guard plane at 0 index
let x = 1 + split.next().unwrap().to_string().parse::<usize>().unwrap();
let y = 1 + split.next().unwrap().to_string().parse::<usize>().unwrap();
let z = 1 + split.next().unwrap().to_string().parse::<usize>().unwrap();
cubes.insert((x, y, z));
max_x = if x > max_x {x} else {max_x};
max_y = if y > max_y {y} else {max_y};
max_z = if z > max_z {z} else {max_z};
}
let mut map = rustsux::Array3D::new(max_x + 1, max_y + 1, max_z + 1, '.');
for (x, y, z) in &cubes {
map.set(*x, *y, *z, '#');
}
println!("{} {} {}", max_x, max_y, max_z);
println!("{:?}", map);
floodfill_surface(map, '#');
Ok(())
}

View File

@ -4,31 +4,60 @@ use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::collections::HashSet;
use std::collections::VecDeque;
type Map = HashSet<(i8, i8, i8)>;
fn floodfill(cubes: Map, max_x: i8, max_y: i8, max_z: i8) -> usize {
let mut visited: Map = HashSet::new();
let mut surfaces = 0;
let mut queue = VecDeque::new();
queue.push_back((0, 0, 0));
println!("cubes = {:?}", cubes);
println!("maxes = {} {} {}", max_x, max_y, max_z);
while let Some((x, y, z)) = queue.pop_front() {
visited.insert((x, y, z));
let all_neighbors = HashSet::from([
(x + 1, y, z), (x - 1, y, z),
(x, y + 1, z), (x, y - 1, z),
(x, y, z + 1), (x, y, z - 1)
]);
surfaces += all_neighbors.intersection(&cubes).count();
all_neighbors.difference(&cubes)
.filter(|&(x, y, z)|
*x >= 0 && *x <= max_x &&
*y >= 0 && *y <= max_y &&
*z >= 0 && *z <= max_z)
.filter(|&cube| !visited.contains(cube))
.for_each(|&cube|
if !queue.contains(&cube) {queue.push_back(cube)});
}
surfaces
}
fn main() -> io::Result<()> {
let input_fname = env::args().nth(1).expect("need input file");
let lines = BufReader::new(File::open(input_fname)?).lines();
let mut cubes: HashSet<(i8, i8, i8)> = HashSet::new();
let mut cubes: Map = HashSet::new();
let (mut max_x, mut max_y, mut max_z) = (0, 0, 0);
for line in lines.flatten() {
let mut split = line.split(',');
let x = split.next().unwrap().to_string().parse::<i8>().unwrap();
let y = split.next().unwrap().to_string().parse::<i8>().unwrap();
let z = split.next().unwrap().to_string().parse::<i8>().unwrap();
// +1 so we have 3 guard planes at 0
let x = 1 + split.next().unwrap().to_string().parse::<i8>().unwrap();
let y = 1 + split.next().unwrap().to_string().parse::<i8>().unwrap();
let z = 1 + split.next().unwrap().to_string().parse::<i8>().unwrap();
cubes.insert((x, y, z));
max_x = if x > max_x {x} else {max_x};
max_y = if y > max_y {y} else {max_y};
max_z = if z > max_z {z} else {max_z};
}
let mut all_neighbors = 0;
for (x, y, z) in &cubes {
let neighbors = HashSet::from([
(*x + 1, *y, *z), (*x - 1, *y, *z),
(*x, *y + 1, *z), (*x, *y - 1, *z),
(*x, *y, *z + 1), (*x, *y, *z - 1)
]);
all_neighbors += cubes.intersection(&neighbors).count();
}
println!("{}", cubes.len() * 6 - all_neighbors);
let surfaces = floodfill(cubes, max_x + 1, max_y + 1, max_z + 1);
println!("answer = {}", surfaces);
Ok(())
}

34
day18/src/main1.rs Normal file
View File

@ -0,0 +1,34 @@
use std::io;
use std::env;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::collections::HashSet;
fn main() -> io::Result<()> {
let input_fname = env::args().nth(1).expect("need input file");
let lines = BufReader::new(File::open(input_fname)?).lines();
let mut cubes: HashSet<(i8, i8, i8)> = HashSet::new();
for line in lines.flatten() {
let mut split = line.split(',');
let x = split.next().unwrap().to_string().parse::<i8>().unwrap();
let y = split.next().unwrap().to_string().parse::<i8>().unwrap();
let z = split.next().unwrap().to_string().parse::<i8>().unwrap();
cubes.insert((x, y, z));
}
let mut all_neighbors = 0;
for (x, y, z) in &cubes {
let neighbors = HashSet::from([
(*x + 1, *y, *z), (*x - 1, *y, *z),
(*x, *y + 1, *z), (*x, *y - 1, *z),
(*x, *y, *z + 1), (*x, *y, *z - 1)
]);
all_neighbors += cubes.intersection(&neighbors).count();
}
println!("{}", cubes.len() * 6 - all_neighbors);
Ok(())
}