mirror of https://github.com/HeNine/aoc2020
day17
parent
4d31c2cd2a
commit
ff25253ca6
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "day17"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["henine <why@no.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
@ -0,0 +1,8 @@
|
|||||||
|
..##.##.
|
||||||
|
#.#..###
|
||||||
|
##.#.#.#
|
||||||
|
#.#.##.#
|
||||||
|
###..#..
|
||||||
|
.#.#..##
|
||||||
|
#.##.###
|
||||||
|
#.#..##.
|
@ -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<ReactorCell> {
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
|||||||
|
.#.
|
||||||
|
..#
|
||||||
|
###
|
Loading…
Reference in New Issue