Advertisement
Guest User

AoC day 22

a guest
Dec 22nd, 2021
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.83 KB | None | 0 0
  1. use std::cmp::{max, min};
  2. use std::collections::HashSet;
  3. use fxhash::FxHashSet;
  4. use itertools::Itertools;
  5.  
  6. pub fn day22_1() {
  7.     let input: Vec<(bool, (i32, i32), (i32, i32), (i32, i32))> = include_str!("../temp22").lines().map(|x| {
  8.         let (state, rest) = x.split_once(" x=").unwrap();
  9.         let (x1, rest) = rest.split_once("..").unwrap();
  10.         let (x2, rest) = rest.split_once(",y=").unwrap();
  11.         let (y1, rest) = rest.split_once("..").unwrap();
  12.         let (y2, rest) = rest.split_once(",z=").unwrap();
  13.         let (z1, z2) = rest.split_once("..").unwrap();
  14.         (state.eq("on"),
  15.          (x1.parse().unwrap(), x2.parse().unwrap()),
  16.          (y1.parse().unwrap(), y2.parse().unwrap()),
  17.          (z1.parse().unwrap(), z2.parse().unwrap()))
  18.     }).collect_vec();
  19.     let mut states = FxHashSet::default();
  20.     for (state, x, y, z) in input {
  21.         if x.1 < -50 || y.1 < -50 || z.1 < -50 || x.0 > 50 || y.0 > 50 || z.0 > 50
  22.         {
  23.             //outside part 1 bounds
  24.             continue;
  25.         }
  26.         //remap the bounds for part 1
  27.         let (x1, x2) = (max(x.0, -50), min(50, x.1));
  28.         let (y1, y2) = (max(y.0, -50), min(50, y.1));
  29.         let (z1, z2) = (max(z.0, -50), min(50, z.1));
  30.         //add stuff
  31.         if state {
  32.             states.extend((x1..=x2).cartesian_product(y1..=y2).cartesian_product(z1..=z2));
  33.         }
  34.         else {
  35.             //remove stuff
  36.             states = states.difference(
  37.                 &FxHashSet::from_iter((x1..=x2).cartesian_product(y1..=y2).cartesian_product(z1..=z2))
  38.                 ).map(|&x| x).collect();
  39.         }
  40.     }
  41.     println!("ANS: {}", states.len());
  42. }
  43.  
  44. #[derive(Debug)]
  45. struct Cube {
  46.     x: [i32; 2],
  47.     y: [i32; 2],
  48.     z: [i32; 2]
  49. }
  50.  
  51. impl Cube {
  52.     fn intersects(&self, other: &Cube) -> bool
  53.     {
  54.         let this_corners = self.get_corners();
  55.         for (x, y, z) in this_corners {
  56.             if x >= other.x[0] && x <= other.x[1] && y >= other.y[0] && y <= other.y[1] && z >= other.z[0] && z <= other.z[1]
  57.             {
  58.                 return true;
  59.             }
  60.         }
  61.         let other_corners = other.get_corners();
  62.         for (x, y, z) in other_corners {
  63.             if x >= self.x[0] && x <= self.x[1] && y >= self.y[0] && y <= self.y[1] && z >= self.z[0] && z <= self.z[1]
  64.             {
  65.                 return true;
  66.             }
  67.         }
  68.         return false;
  69.     }
  70.  
  71.     fn intersects2(&self, other: &Cube) -> bool
  72.     {
  73.         self.x[0] <= other.x[1] && self.x[1] >= other.x[0]
  74.             && self.y[0] <= other.y[1] && self.y[1] >= other.y[0]
  75.             && self.z[0] <= other.z[1] && self.z[1] >= other.z[0]
  76.     }
  77.  
  78.     fn get_corners(&self) -> Vec<(i32, i32, i32)> {
  79.         self.x.iter().cartesian_product(self.y.iter()).cartesian_product(self.z.iter()).map(|(xy, (z))| (*xy.0, *xy.1, *z)).collect_vec()
  80.     }
  81.  
  82.     fn cut(mut self, other: &Cube) -> Vec<Cube>
  83.     {
  84.         //let (selfx, selfy, selfz) = (self.x, self.y, self.z)
  85.         let mut ret = Vec::new();
  86.         if self.x[0] < other.x[0] {
  87.             ret.push(Cube {
  88.                 x: [self.x[0], other.x[0] - 1],
  89.                 y: self.y,
  90.                 z: self.z,
  91.             });
  92.             self.x[0] = other.x[0];
  93.         }
  94.         if self.x[1] > other.x[1] {
  95.             ret.push(Cube {
  96.                 x: [other.x[1] + 1, self.x[1]],
  97.                 y: self.y,
  98.                 z: self.z,
  99.             });
  100.             self.x[1] = other.x[1];
  101.         }
  102.         //y
  103.         if self.y[0] < other.y[0] {
  104.             ret.push(Cube {
  105.                 x: self.x,
  106.                 y: [self.y[0], other.y[0] - 1],
  107.                 z: self.z,
  108.             });
  109.             self.y[0] = other.y[0];
  110.         }
  111.         if self.y[1] > other.y[1] {
  112.             ret.push(Cube {
  113.                 x: self.x,
  114.                 y: [other.y[1] + 1, self.y[1]],
  115.                 z: self.z,
  116.             });
  117.             self.y[1] = other.y[1];
  118.         }
  119.         //z
  120.         if self.z[0] < other.z[0] {
  121.             ret.push(Cube {
  122.                 x: self.x,
  123.                 y: self.y,
  124.                 z: [self.z[0], other.z[0] - 1],
  125.             });
  126.             self.z[0] = other.z[0];
  127.         }
  128.         if self.z[1] > other.z[1] {
  129.             ret.push(Cube {
  130.                 x: self.x,
  131.                 y: self.y,
  132.                 z: [other.z[1] + 1, self.z[1]],
  133.             });
  134.             self.z[1] = other.z[1];
  135.         }
  136.         return ret;
  137.     }
  138.  
  139.     fn vol(&self) -> usize
  140.     {
  141.         ((self.x[1] - self.x[0]) as usize + 1) *
  142.             ((self.y[1] - self.y[0]) as usize + 1) *
  143.             ((self.z[1] - self.z[0]) as usize + 1)
  144.     }
  145. }
  146.  
  147.  
  148. pub fn day22_2() {
  149.     let mut states: Vec<Cube> = Vec::default();
  150.     let input: Vec<(bool, [i32; 2], [i32; 2], [i32; 2])> = include_str!("../temp22").lines().map(|x| {
  151.         let (state, rest) = x.split_once(" x=").unwrap();
  152.         let (x1, rest) = rest.split_once("..").unwrap();
  153.         let (x2, rest) = rest.split_once(",y=").unwrap();
  154.         let (y1, rest) = rest.split_once("..").unwrap();
  155.         let (y2, rest) = rest.split_once(",z=").unwrap();
  156.         let (z1, z2) = rest.split_once("..").unwrap();
  157.         (state.eq("on"),
  158.          [x1.parse().unwrap(), x2.parse().unwrap()],
  159.          [y1.parse().unwrap(), y2.parse().unwrap()],
  160.          [z1.parse().unwrap(), z2.parse().unwrap()])
  161.     }).collect_vec();
  162.     for (state, x, y, z) in input {
  163.         let this = Cube{x, y, z};
  164.         //remove all intersections to get rid of overlap
  165.         let mut newCubes = states.drain_filter(|other| other.intersects2(&this)).flat_map(|other| other.cut(&this)).collect();
  166.         states.append(&mut newCubes);
  167.         if state {
  168.             //add the now non intersected thing.
  169.             states.push(this)
  170.         }
  171.     }
  172.     println!("ANS: {}", states.iter().fold(0, |acc, x | acc + x.vol()));
  173. }
  174.  
  175.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement