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::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
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