summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-22 01:51:08 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-22 01:51:08 -0500
commitfef4686990b7c97cafedf740feafefd6fcf51bb8 (patch)
tree841da8a0f532e5f13d41e05782bae6bd5460a947 /src
parentc043a9b39dad5b3a45e1ee61f65edc8d695755b6 (diff)
downloadadvent-of-code-fef4686990b7c97cafedf740feafefd6fcf51bb8.tar.gz
advent-of-code-fef4686990b7c97cafedf740feafefd6fcf51bb8.zip
day 22
Diffstat (limited to 'src')
-rw-r--r--src/2021/22/mod.rs153
-rw-r--r--src/2021/mod.rs4
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)),
}