day18.rs (2940B)
1 fn adjescent(p: &(usize,usize,usize), mx:usize) -> Vec<(usize,usize,usize)> { 2 let mut v = vec![]; 3 if p.0+1 < mx { 4 v.push((p.0+1,p.1,p.2)); 5 } 6 if p.1+1 < mx { 7 v.push((p.0,p.1+1,p.2)); 8 } 9 if p.2+1 < mx { 10 v.push((p.0,p.1,p.2+1)); 11 } 12 if p.0 > 0 { 13 v.push((p.0-1,p.1,p.2)); 14 } 15 if p.1 > 0 { 16 v.push((p.0,p.1-1,p.2)); 17 } 18 if p.2 > 0 { 19 v.push((p.0,p.1,p.2-1)); 20 } 21 v 22 } 23 24 #[derive(Debug,PartialEq)] 25 enum State {Rock,Unknown,OutsideAir} 26 27 fn mark_outside(grid: &mut Vec<Vec<Vec<State>>>, curr: &(usize,usize,usize), mx: usize) { 28 for cell in adjescent(curr, mx) { 29 if let State::Unknown = grid[cell.0][cell.1][cell.2] { 30 grid[cell.0][cell.1][cell.2] = State::OutsideAir; 31 mark_outside(grid, &cell, mx); 32 } 33 } 34 } 35 36 fn surface_area(grid: &Vec<Vec<Vec<State>>>, cubes: &Vec<(usize,usize,usize)>, mx: usize) -> usize { 37 let surface_area: usize = cubes.iter().map(|cube| { 38 let mut score = 6; 39 for p in adjescent(cube, mx) { 40 if let State::Rock = grid[p.0][p.1][p.2] { 41 score -= 1; 42 } 43 } 44 score 45 }).sum(); 46 surface_area 47 } 48 49 pub fn run(input:String) { 50 let cubes = input.lines() 51 .map(|line| { 52 let res = line.split(",").map(|t| {t.parse::<usize>().unwrap()}).collect::<Vec<usize>>(); 53 if res.len() != 3 { 54 panic!("malformatted line! {}", line); 55 } 56 (res[0], res[1], res[2]) 57 }).collect::<Vec<(usize,usize,usize)>>(); 58 let mx: usize = cubes.iter().map(|t| {vec![t.0, t.1, t.2]}).flatten().max().unwrap() + 3; 59 // Allocate a 3d space, and mark the rocky cubes 60 let mut grid: Vec<Vec<Vec<State>>> = (0..mx).map(|_| {(0..mx).map(|_| {(0..mx).map(|_| {State::Unknown}).collect()}).collect()}).collect(); 61 for cube in cubes.iter() { 62 grid[cube.0][cube.1][cube.2] = State::Rock; 63 } 64 // Now count cubes. Each contributes 6, minus number of adjescent rocky cubes 65 66 println!("Day 18 pt1: {}", surface_area(&grid, &cubes, mx)); 67 // So... how can I remove pockets of air to get the _outside_ surface area? 68 // ans; fill in the inside areas! 69 // pick a spot definitely on the outside;; iterate out until all the outside is marked. 70 // Anything remaining is pockets, fill it in, re-calculate the outside surface area. 71 grid[0][0][0] = State::OutsideAir; 72 mark_outside(&mut grid, &(0,0,0), mx); 73 // All remaining Unknown cells are air pockets, fill 'em in 74 for x in 0..mx { 75 for y in 0..mx { 76 for z in 0..mx { 77 match grid[x][y][z] { 78 State::Unknown => { 79 grid[x][y][z] = State::Rock; 80 }, 81 _ => () 82 }; 83 } 84 } 85 } 86 // recalculate the surface area 87 println!("Day 18 pt2: {}", surface_area(&grid, &cubes, mx)); 88 }