diff --git a/day18/src/main.array3d.rs b/day18/src/main.array3d.rs new file mode 100644 index 0000000..fc74155 --- /dev/null +++ b/day18/src/main.array3d.rs @@ -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 { + backing_vec: Vec, + pub d1: usize, pub d2: usize, pub d3: usize, + } + + impl Array3D { + pub fn new(d1: usize, d2: usize, d3: usize, init: T) -> Array3D { + 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 fmt::Debug for Array3D { + 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(map: rustsux::Array3D, 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::().unwrap(); + let y = 1 + split.next().unwrap().to_string().parse::().unwrap(); + let z = 1 + split.next().unwrap().to_string().parse::().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(()) +} + diff --git a/day18/src/main.rs b/day18/src/main.rs index ba7fc15..89677ae 100644 --- a/day18/src/main.rs +++ b/day18/src/main.rs @@ -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::().unwrap(); - let y = split.next().unwrap().to_string().parse::().unwrap(); - let z = split.next().unwrap().to_string().parse::().unwrap(); + // +1 so we have 3 guard planes at 0 + let x = 1 + split.next().unwrap().to_string().parse::().unwrap(); + let y = 1 + split.next().unwrap().to_string().parse::().unwrap(); + let z = 1 + split.next().unwrap().to_string().parse::().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(()) } diff --git a/day18/src/main1.rs b/day18/src/main1.rs new file mode 100644 index 0000000..ba7fc15 --- /dev/null +++ b/day18/src/main1.rs @@ -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::().unwrap(); + let y = split.next().unwrap().to_string().parse::().unwrap(); + let z = split.next().unwrap().to_string().parse::().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(()) +} +