diff options
author | Jesse Luehrs <doy@tozt.net> | 2021-12-22 01:51:08 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2021-12-22 01:51:08 -0500 |
commit | fef4686990b7c97cafedf740feafefd6fcf51bb8 (patch) | |
tree | 841da8a0f532e5f13d41e05782bae6bd5460a947 /src | |
parent | c043a9b39dad5b3a45e1ee61f65edc8d695755b6 (diff) | |
download | advent-of-code-fef4686990b7c97cafedf740feafefd6fcf51bb8.tar.gz advent-of-code-fef4686990b7c97cafedf740feafefd6fcf51bb8.zip |
day 22
Diffstat (limited to 'src')
-rw-r--r-- | src/2021/22/mod.rs | 153 | ||||
-rw-r--r-- | src/2021/mod.rs | 4 |
2 files changed, 157 insertions, 0 deletions
diff --git a/src/2021/22/mod.rs b/src/2021/22/mod.rs new file mode 100644 index 0000000..8348693 --- /dev/null +++ b/src/2021/22/mod.rs @@ -0,0 +1,153 @@ +use crate::prelude::*; + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +struct Point3D { + x: i64, + y: i64, + z: i64, +} + +impl Point3D { + fn new(x: i64, y: i64, z: i64) -> Self { + Self { x, y, z } + } +} + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +struct Range3D { + x: std::ops::RangeInclusive<i64>, + y: std::ops::RangeInclusive<i64>, + z: std::ops::RangeInclusive<i64>, +} + +impl Range3D { + fn new( + x: std::ops::RangeInclusive<i64>, + y: std::ops::RangeInclusive<i64>, + z: std::ops::RangeInclusive<i64>, + ) -> Self { + Self { x, y, z } + } + + fn contains(&self, point: &Point3D) -> bool { + self.x.contains(&point.x) + && self.y.contains(&point.y) + && self.z.contains(&point.z) + } +} + +#[derive(Debug, Clone)] +struct Rule { + on: bool, + range: Range3D, +} + +impl Rule { + fn parse(line: &str) -> Self { + let captures = regex_captures!( + r"^(\w+) x=(-?\d+)..(-?\d+),y=(-?\d+)..(-?\d+),z=(-?\d+)..(-?\d+)$", + line + ) + .unwrap(); + Self { + on: &captures[1] == "on", + range: Range3D::new( + captures[2].parse().unwrap()..=captures[3].parse().unwrap(), + captures[4].parse().unwrap()..=captures[5].parse().unwrap(), + captures[6].parse().unwrap()..=captures[7].parse().unwrap(), + ), + } + } + + fn contains(&self, point: &Point3D) -> Option<bool> { + if self.range.contains(point) { + Some(self.on) + } else { + None + } + } +} + +#[derive(Debug)] +pub struct Reactor { + rules: Vec<Rule>, +} + +impl Reactor { + fn parse(lines: impl Iterator<Item = String>) -> Self { + Self { + rules: lines.map(|line| Rule::parse(&line)).collect(), + } + } + + fn on(&self, point: &Point3D) -> bool { + for rule in self.rules.iter().rev() { + if let Some(on) = rule.contains(point) { + return on; + } + } + false + } +} + +pub fn parse(fh: File) -> Result<Reactor> { + Ok(Reactor::parse(parse::lines(fh))) +} + +pub fn part1(reactor: Reactor) -> Result<i64> { + let mut total = 0; + for x in -50..=50 { + for y in -50..=50 { + for z in -50..=50 { + if reactor.on(&Point3D::new(x, y, z)) { + total += 1; + } + } + } + } + Ok(total) +} + +pub fn part2(reactor: Reactor) -> Result<i64> { + let mut x = vec![]; + let mut y = vec![]; + let mut z = vec![]; + for rule in &reactor.rules { + x.push(*rule.range.x.start()); + x.push(rule.range.x.end() + 1); + y.push(*rule.range.y.start()); + y.push(rule.range.y.end() + 1); + z.push(*rule.range.z.start()); + z.push(rule.range.z.end() + 1); + } + x.sort_unstable(); + y.sort_unstable(); + z.sort_unstable(); + + let mut total = 0; + for i in 0..(x.len() - 1) { + eprintln!("{}", i); + for j in 0..(y.len() - 1) { + for k in 0..(z.len() - 1) { + if reactor.on(&Point3D::new(x[i], y[j], z[k])) { + total += (x[i + 1] - x[i]) + * (y[j + 1] - y[j]) + * (z[k + 1] - z[k]) + } + } + } + } + Ok(total) +} + +#[test] +fn test() { + assert_eq!( + part1(parse(parse::data(2021, 22).unwrap()).unwrap()).unwrap(), + 0 + ); + assert_eq!( + part2(parse(parse::data(2021, 22).unwrap()).unwrap()).unwrap(), + 0 + ); +} diff --git a/src/2021/mod.rs b/src/2021/mod.rs index 4931707..124ea71 100644 --- a/src/2021/mod.rs +++ b/src/2021/mod.rs @@ -42,6 +42,8 @@ mod day19; mod day20; #[path = "21/mod.rs"] mod day21; +#[path = "22/mod.rs"] +mod day22; // NEXT MOD pub fn run(day: u8, puzzle: u8) -> Result<i64> { @@ -88,6 +90,8 @@ pub fn run(day: u8, puzzle: u8) -> Result<i64> { (20, 2) => day20::part2(day20::parse(parse::data(2021, 20)?)?), (21, 1) => day21::part1(day21::parse(parse::data(2021, 21)?)?), (21, 2) => day21::part2(day21::parse(parse::data(2021, 21)?)?), + (22, 1) => day22::part1(day22::parse(parse::data(2021, 22)?)?), + (22, 2) => day22::part2(day22::parse(parse::data(2021, 22)?)?), // NEXT PART _ => Err(anyhow!("unknown puzzle {}-{}", day, puzzle)), } |