From 564d55c5d2c63c82e6b4691601e439e5a84f12bd Mon Sep 17 00:00:00 2001 From: Martin Ashby Date: Fri, 23 Dec 2022 16:40:35 +0000 Subject: day18 pt2 --- src/day18.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/src/day18.rs b/src/day18.rs index 636b342..ffb25ad 100644 --- a/src/day18.rs +++ b/src/day18.rs @@ -1,8 +1,14 @@ -fn adjescent(p: &(usize,usize,usize)) -> Vec<(usize,usize,usize)> { +fn adjescent(p: &(usize,usize,usize), mx:usize) -> Vec<(usize,usize,usize)> { let mut v = vec![]; - v.push((p.0+1,p.1,p.2)); - v.push((p.0,p.1+1,p.2)); - v.push((p.0,p.1,p.2+1)); + if p.0+1 < mx { + v.push((p.0+1,p.1,p.2)); + } + if p.1+1 < mx { + v.push((p.0,p.1+1,p.2)); + } + if p.2+1 < mx { + v.push((p.0,p.1,p.2+1)); + } if p.0 > 0 { v.push((p.0-1,p.1,p.2)); } @@ -15,6 +21,31 @@ fn adjescent(p: &(usize,usize,usize)) -> Vec<(usize,usize,usize)> { v } +#[derive(Debug,PartialEq)] +enum State {Rock,Unknown,OutsideAir} + +fn mark_outside(grid: &mut Vec>>, curr: &(usize,usize,usize), mx: usize) { + for cell in adjescent(curr, mx) { + if let State::Unknown = grid[cell.0][cell.1][cell.2] { + grid[cell.0][cell.1][cell.2] = State::OutsideAir; + mark_outside(grid, &cell, mx); + } + } +} + +fn surface_area(grid: &Vec>>, cubes: &Vec<(usize,usize,usize)>, mx: usize) -> usize { + let surface_area: usize = cubes.iter().map(|cube| { + let mut score = 6; + for p in adjescent(cube, mx) { + if let State::Rock = grid[p.0][p.1][p.2] { + score -= 1; + } + } + score + }).sum(); + surface_area +} + pub fn run(input:String) { let cubes = input.lines() .map(|line| { @@ -25,20 +56,33 @@ pub fn run(input:String) { (res[0], res[1], res[2]) }).collect::>(); let mx: usize = cubes.iter().map(|t| {vec![t.0, t.1, t.2]}).flatten().max().unwrap() + 3; - // Allocate a 3d space.. - let mut grid: Vec>> = (0..mx).map(|_| {(0..mx).map(|_| {(0..mx).map(|_| {false}).collect()}).collect()}).collect(); + // Allocate a 3d space, and mark the rocky cubes + let mut grid: Vec>> = (0..mx).map(|_| {(0..mx).map(|_| {(0..mx).map(|_| {State::Unknown}).collect()}).collect()}).collect(); for cube in cubes.iter() { - grid[cube.0][cube.1][cube.2] = true; + grid[cube.0][cube.1][cube.2] = State::Rock; } - // Now count cubes. Each contributes 6,minus number of connections - let surface_area: usize = cubes.iter().map(|cube| { - let mut score = 6; - for p in adjescent(cube) { - if grid[p.0][p.1][p.2] { - score -= 1; + // Now count cubes. Each contributes 6, minus number of adjescent rocky cubes + + println!("Day 18 pt1: {}", surface_area(&grid, &cubes, mx)); + // So... how can I remove pockets of air to get the _outside_ surface area? + // ans; fill in the inside areas! + // pick a spot definitely on the outside;; iterate out until all the outside is marked. + // Anything remaining is pockets, fill it in, re-calculate the outside surface area. + grid[0][0][0] = State::OutsideAir; + mark_outside(&mut grid, &(0,0,0), mx); + // All remaining Unknown cells are air pockets, fill 'em in + for x in 0..mx { + for y in 0..mx { + for z in 0..mx { + match grid[x][y][z] { + State::Unknown => { + grid[x][y][z] = State::Rock; + }, + _ => () + }; } } - score - }).sum(); - println!("Day 18: {}", surface_area); + } + // recalculate the surface area + println!("Day 18 pt2: {}", surface_area(&grid, &cubes, mx)); } \ No newline at end of file -- cgit v1.2.3-ZIG