aoc2022

Advent of Code 2022 solutions in Rust
git clone git://code.mfashby.net:/aoc2022
Log | Files | Refs

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 }