From ff25253ca69a75ffe8b6efa8a8af80b9812b3195 Mon Sep 17 00:00:00 2001 From: henine Date: Thu, 17 Dec 2020 11:19:46 +0100 Subject: [PATCH] day17 --- day17/Cargo.toml | 9 +++ day17/input | 8 +++ day17/src/main.rs | 136 ++++++++++++++++++++++++++++++++++++++++++++++ day17/test | 3 + 4 files changed, 156 insertions(+) create mode 100644 day17/Cargo.toml create mode 100644 day17/input create mode 100644 day17/src/main.rs create mode 100644 day17/test diff --git a/day17/Cargo.toml b/day17/Cargo.toml new file mode 100644 index 0000000..e451294 --- /dev/null +++ b/day17/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day17" +version = "0.1.0" +authors = ["henine "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day17/input b/day17/input new file mode 100644 index 0000000..8d6105a --- /dev/null +++ b/day17/input @@ -0,0 +1,8 @@ +..##.##. +#.#..### +##.#.#.# +#.#.##.# +###..#.. +.#.#..## +#.##.### +#.#..##. \ No newline at end of file diff --git a/day17/src/main.rs b/day17/src/main.rs new file mode 100644 index 0000000..7ab2549 --- /dev/null +++ b/day17/src/main.rs @@ -0,0 +1,136 @@ +use std::cmp::{max, min}; +use std::collections::HashMap; +use std::fs::File; +use std::io::{BufRead, BufReader}; + +use crate::ReactorCell::{Active, Inactive}; + +type Reactor = HashMap<(i32, i32, i32, i32), ReactorCell>; + +#[derive(Copy, Clone, Debug)] +enum ReactorCell { + Active(i32, i32, i32, i32), + Inactive(i32, i32, i32, i32), +} + +impl ReactorCell { + fn new(state: char, x: i32, y: i32, z: i32, w: i32) -> Self { + match state { + '.' => Inactive(x, y, z, w), + '#' => Active(x, y, z, w), + _ => panic!() + } + } + + fn update(&self, reactor: &Reactor) -> Option { + let (selfx, selfy, selfz, selfw) = match self { + Active(x, y, z, w) | Inactive(x, y, z, w) => (*x, *y, *z, *w) + }; + + let mut count = 0; + for x in -1..=1 { + for y in -1..=1 { + for z in -1..=1 { + for w in -1..=1 { + if x == 0 && y == 0 && z == 0 && w == 0 { continue; }; + count += match reactor.get(&(selfx + x, selfy + y, selfz + z, selfw + w)) { + Some(Active(..)) => 1, + None | Some(Inactive(..)) => 0 + } + } + } + } + } + + match self { + Inactive(x, y, z, w) => if count == 3 { Some(Active(*x, *y, *z, *w)) } else { None }, + Active(x, y, z, w) => if count == 2 || count == 3 { Some(Active(*x, *y, *z, *w)) } else { None } + } + } +} + +fn main() { + let file = File::open("input").unwrap(); + let file_buffer = BufReader::new(file); + let mut lines = file_buffer.lines(); + + + let mut reactor = Reactor::new(); + + let mut y = 0; + while let Some(Ok(line)) = lines.next() { + for (x, state) in line.chars().enumerate() { + reactor.insert((x as i32, y, 0, 0), ReactorCell::new(state, x as i32, y, 0, 0)); + } + y += 1; + } + + print_z(&reactor, 0); + + for _ in 0..6 { + let mut new_reactor = Reactor::new(); + let (min_x, min_y, min_z,min_w, + max_x, max_y, max_z, max_w) = get_boundaries(&reactor); + for x in min_x - 1..=max_x + 1 { + for y in min_y - 1..=max_y + 1 { + for z in min_z - 1..=max_z + 1 { + for w in min_w-1..=max_w+1 { + let new_cell = match reactor.get(&(x, y, z, w)) { + Some(x) => x.update(&reactor), + None => Inactive(x, y, z, w).update(&reactor) + }; + + match new_cell { + Some(Active(x, y, z,w)) => new_reactor.insert((x, y, z,w), new_cell.unwrap()), + Some(Inactive(..)) | None => None + }; + } + } + } + } + + reactor = new_reactor; + // for z in min_z..max_z { + // println!("z={}", z); + // print_z(&reactor, z) + // } + } + + let count = reactor.values().filter(|cell| match cell { + Active(..) => true, + _ => false + }).count(); + println!("{}", count); +} + +fn print_z(reactor: &Reactor, z: i32) { + let (min_x, min_y, _, _, max_x, max_y, _, _) = get_boundaries(reactor); + + for y in min_y..=max_y { + for x in min_x..=max_x { + print!("{}", match reactor.get(&(x, y, z, 0)) { + Some(Active(..)) => '#', + Some(Inactive(..)) | None => '.' + }) + } + println!(); + } + println!(); +} + +fn get_boundaries(reactor: &Reactor) -> (i32, i32, i32,i32, + i32, i32, i32,i32) { + reactor.iter() + .filter(|(_, state)| match state { + Active(..) => true, + Inactive(..) => false + }) + .fold((i32::MAX, i32::MAX, i32::MAX, i32::MAX, + i32::MIN, i32::MIN, i32::MIN,i32::MIN), + |(minx, miny, minz, minw, maxx, maxy, maxz,maxw), ((x, y, z, w), _)| { + (min(minx, *x), min(miny, *y), min(minz, *z), min(minw, *w), + max(maxx, *x), max(maxy, *y), max(maxz, *z), max(maxw, *w)) + } + ) +} + diff --git a/day17/test b/day17/test new file mode 100644 index 0000000..17630fd --- /dev/null +++ b/day17/test @@ -0,0 +1,3 @@ +.#. +..# +### \ No newline at end of file