d18p2
This commit is contained in:
parent
5d522dc0f6
commit
976cb3651c
93
day18/src/main.array3d.rs
Normal file
93
day18/src/main.array3d.rs
Normal 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(())
|
||||||
|
}
|
||||||
|
|
@ -4,31 +4,60 @@ use std::fs::File;
|
|||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use std::collections::HashSet;
|
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<()> {
|
fn main() -> io::Result<()> {
|
||||||
let input_fname = env::args().nth(1).expect("need input file");
|
let input_fname = env::args().nth(1).expect("need input file");
|
||||||
let lines = BufReader::new(File::open(input_fname)?).lines();
|
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() {
|
for line in lines.flatten() {
|
||||||
let mut split = line.split(',');
|
let mut split = line.split(',');
|
||||||
let x = split.next().unwrap().to_string().parse::<i8>().unwrap();
|
// +1 so we have 3 guard planes at 0
|
||||||
let y = split.next().unwrap().to_string().parse::<i8>().unwrap();
|
let x = 1 + split.next().unwrap().to_string().parse::<i8>().unwrap();
|
||||||
let z = 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));
|
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;
|
let surfaces = floodfill(cubes, max_x + 1, max_y + 1, max_z + 1);
|
||||||
for (x, y, z) in &cubes {
|
println!("answer = {}", surfaces);
|
||||||
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
day18/src/main1.rs
Normal file
34
day18/src/main1.rs
Normal 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(())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user