Day17 + formatting

This commit is contained in:
Daniel S. 2020-12-17 15:25:30 +01:00
parent 7acfca5132
commit 818271e4ad
4 changed files with 166 additions and 3 deletions

78
src/day17p1.rs Normal file
View File

@ -0,0 +1,78 @@
use aoc_runner_derive::{aoc, aoc_generator};
use std::collections::HashSet;
#[derive(Clone)]
pub struct Data {
active: HashSet<(i64, i64, i64)>,
}
impl Data {
pub fn count_neighbors(&self, x: i64, y: i64, z: i64) -> usize {
let mut ret = 0;
for dx in &[-1, 0, 1] {
for dy in &[-1, 0, 1] {
for dz in &[-1, 0, 1] {
if (*dx == 0) && (*dy == 0) && (*dz == 0) {
continue;
}
let is_active = self.active.contains(&(x + dx, y + dy, z + dz));
if is_active {
ret += 1;
}
}
}
}
ret
}
pub fn update(&mut self) {
let mut checked = HashSet::new();
let mut next_active = HashSet::new();
for &(x, y, z) in &self.active {
for &dx in &[-1, 0, 1] {
for &dy in &[-1, 0, 1] {
for &dz in &[-1, 0, 1] {
let (nx, ny, nz) = (x + dx, y + dy, z + dz);
if !checked.insert((nx, ny, nz)) {
continue;
}
let nb = self.count_neighbors(nx, ny, nz);
let is_active = self.active.contains(&(nx, ny, nz));
if is_active && (nb == 2 || nb == 3) {
next_active.insert((nx, ny, nz));
} else if !is_active && nb == 3 {
next_active.insert((nx, ny, nz));
}
}
}
}
}
self.active = next_active;
}
pub fn count(&self) -> usize {
return self.active.len();
}
}
#[aoc_generator(day17, part1)]
pub fn input_generator(input: &str) -> Data {
let mut active = HashSet::new();
let z = 0;
for (y, line) in input.trim().lines().enumerate() {
for (x, c) in line.trim().chars().enumerate() {
if c == '#' {
active.insert((x as i64, y as i64, z as i64));
}
}
}
return Data { active };
}
#[aoc(day17, part1)]
pub fn solve_part1(input: &Data) -> usize {
let mut data = input.clone();
for _ in 0..6 {
data.update()
}
return data.count();
}

83
src/day17p2.rs Normal file
View File

@ -0,0 +1,83 @@
use aoc_runner_derive::{aoc, aoc_generator};
use std::collections::HashSet;
#[derive(Clone)]
pub struct Data {
active: HashSet<(i64, i64, i64, i64)>,
}
impl Data {
pub fn count_neighbors(&self, x: i64, y: i64, z: i64, w: i64) -> usize {
let mut ret = 0;
for dx in &[-1, 0, 1] {
for dy in &[-1, 0, 1] {
for dz in &[-1, 0, 1] {
for dw in &[-1, 0, 1] {
if (*dx == 0) && (*dy == 0) && (*dz == 0) && (*dw == 0) {
continue;
}
let is_active = self.active.contains(&(x + dx, y + dy, z + dz, w + dw));
if is_active {
ret += 1;
}
}
}
}
}
ret
}
pub fn update(&mut self) {
let mut checked = HashSet::new();
let mut next_active = HashSet::new();
for &(x, y, z, w) in &self.active {
for &dx in &[-1, 0, 1] {
for &dy in &[-1, 0, 1] {
for &dz in &[-1, 0, 1] {
for &dw in &[-1, 0, 1] {
let (nx, ny, nz, nw) = (x + dx, y + dy, z + dz, w + dw);
if !checked.insert((nx, ny, nz, nw)) {
continue;
}
let nb = self.count_neighbors(nx, ny, nz, nw);
let is_active = self.active.contains(&(nx, ny, nz, nw));
if is_active && (nb == 2 || nb == 3) {
next_active.insert((nx, ny, nz, nw));
} else if !is_active && nb == 3 {
next_active.insert((nx, ny, nz, nw));
}
}
}
}
}
}
self.active = next_active;
}
pub fn count(&self) -> usize {
return self.active.len();
}
}
#[aoc_generator(day17, part2)]
pub fn input_generator(input: &str) -> Data {
let mut active = HashSet::new();
let z = 0;
let w = 0;
for (y, line) in input.trim().lines().enumerate() {
for (x, c) in line.trim().chars().enumerate() {
if c == '#' {
active.insert((x as i64, y as i64, z as i64, w as i64));
}
}
}
return Data { active };
}
#[aoc(day17, part2)]
pub fn solve_part1(input: &Data) -> usize {
let mut data = input.clone();
for _ in 0..6 {
data.update()
}
return data.count();
}

View File

@ -15,4 +15,6 @@ pub mod day13;
pub mod day14;
pub mod day15;
pub mod day16;
pub mod day17p1;
pub mod day17p2;
aoc_lib! { year = 2020 }