From cc7dfbef915ad5abf38de084f99d0224ed8e8eca Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Thu, 17 Dec 2020 15:12:45 +0100 Subject: [PATCH] Added day 17 --- inputs/day17.txt | 8 +++ inputs/test.txt | 14 ++--- src/bin/day17.rs | 111 +++++++++++++++++++++++++++++++++++++++ src/bin/day17_part2.rs | 114 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 236 insertions(+), 11 deletions(-) create mode 100644 inputs/day17.txt create mode 100644 src/bin/day17.rs create mode 100644 src/bin/day17_part2.rs diff --git a/inputs/day17.txt b/inputs/day17.txt new file mode 100644 index 0000000..eb42f70 --- /dev/null +++ b/inputs/day17.txt @@ -0,0 +1,8 @@ +...#...# +..##.#.# +###..#.. +........ +...##.#. +.#.####. +...####. +..##...# diff --git a/inputs/test.txt b/inputs/test.txt index b48bf37..eedd3d2 100644 --- a/inputs/test.txt +++ b/inputs/test.txt @@ -1,11 +1,3 @@ -class: 0-1 or 4-19 -row: 0-5 or 8-19 -seat: 0-13 or 16-19 - -your ticket: -11,12,13 - -nearby tickets: -3,9,18 -15,1,5 -5,14,9 +.#. +..# +### diff --git a/src/bin/day17.rs b/src/bin/day17.rs new file mode 100644 index 0000000..8cc1ba8 --- /dev/null +++ b/src/bin/day17.rs @@ -0,0 +1,111 @@ +use std::collections::{HashMap, HashSet}; +use std::error::Error; +use std::fs::File; +use std::io::{self, BufRead}; +use std::vec::Vec; + +#[derive(PartialEq, Copy, Clone, Debug)] +enum CubeState { + Active, + Inactive, +} + +fn enumerate_adjacent(x: i32, y: i32, z: i32) -> Vec<(i32, i32, i32)> { + let mut res: Vec<(i32, i32, i32)> = Vec::new(); + for dx in -1..2 { + for dy in -1..2 { + for dz in -1..2 { + if dx != 0 || dy != 0 || dz != 0 { + res.push((x + dx, y + dy, z + dz)); + } + } + } + } + + res +} + +fn count_adjacent_active( + x: i32, + y: i32, + z: i32, + world: &HashMap<(i32, i32, i32), CubeState>, +) -> u32 { + enumerate_adjacent(x, y, z) + .iter() + .map(|coords| match world.get(&coords) { + Some(CubeState::Active) => 1, + _ => 0, + }) + .fold(0u32, |x, acc| x + acc) +} + +fn main() -> Result<(), Box> { + let file = File::open("inputs/day17.txt")?; + let lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); + + let mut world: HashMap<(i32, i32, i32), CubeState> = HashMap::new(); + + let initial_slice: Vec<(i32, i32, i32, CubeState)> = lines + .enumerate() + .map(|(y, l)| { + l.chars() + .enumerate() + .map(|(x, c)| match c { + '#' => (x as i32, y as i32, 0, CubeState::Active), + '.' => (x as i32, y as i32, 0, CubeState::Inactive), + _ => panic!("Unknown State: {}", c), + }) + .collect::>() + }) + .fold(Vec::new(), |mut acc, mut x| { + acc.append(&mut x); + acc + }); + + for (x, y, z, s) in initial_slice { + world.insert((x, y, z), s); + } + + for _ in 0..6 { + let mut used_positions: HashSet<(i32, i32, i32)> = HashSet::new(); + for (x, y, z) in world.keys() { + for coords in enumerate_adjacent(*x, *y, *z) { + used_positions.insert(coords); + } + } + + let mut new_world: HashMap<(i32, i32, i32), CubeState> = HashMap::new(); + for (x, y, z) in used_positions { + let cur_state = if let Some(state) = world.get(&(x, y, z)) { + *state + } else { + CubeState::Inactive + }; + + let active_adjacent = count_adjacent_active(x, y, z, &world); + + if cur_state == CubeState::Active && (active_adjacent == 2 || active_adjacent == 3) { + new_world.insert((x, y, z), CubeState::Active); + } else if cur_state == CubeState::Inactive && active_adjacent == 3 { + new_world.insert((x, y, z), CubeState::Active); + } else { + new_world.insert((x, y, z), CubeState::Inactive); + }; + } + + world = new_world; + } + + let active_count = world + .values() + .map(|s| match s { + CubeState::Active => 1, + _ => 0, + }) + .fold(0, |acc, x| x + acc); + + println!("Active Cells: {}", active_count); + + Ok(()) +} diff --git a/src/bin/day17_part2.rs b/src/bin/day17_part2.rs new file mode 100644 index 0000000..333666e --- /dev/null +++ b/src/bin/day17_part2.rs @@ -0,0 +1,114 @@ +use std::collections::{HashMap, HashSet}; +use std::error::Error; +use std::fs::File; +use std::io::{self, BufRead}; +use std::vec::Vec; + +#[derive(PartialEq, Copy, Clone, Debug)] +enum CubeState { + Active, + Inactive, +} + +fn enumerate_adjacent(x: i32, y: i32, z: i32, w: i32) -> Vec<(i32, i32, i32, i32)> { + let mut res: Vec<(i32, i32, i32, i32)> = Vec::new(); + for dx in -1..2 { + for dy in -1..2 { + for dz in -1..2 { + for dw in -1..2 { + if dx != 0 || dy != 0 || dz != 0 || dw != 0 { + res.push((x + dx, y + dy, z + dz, w + dw)); + } + } + } + } + } + + res +} + +fn count_adjacent_active( + x: i32, + y: i32, + z: i32, + w: i32, + world: &HashMap<(i32, i32, i32, i32), CubeState>, +) -> u32 { + enumerate_adjacent(x, y, z, w) + .iter() + .map(|coords| match world.get(&coords) { + Some(CubeState::Active) => 1, + _ => 0, + }) + .fold(0u32, |x, acc| x + acc) +} + +fn main() -> Result<(), Box> { + let file = File::open("inputs/day17.txt")?; + let lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); + + let mut world: HashMap<(i32, i32, i32, i32), CubeState> = HashMap::new(); + + let initial_slice: Vec<(i32, i32, i32, i32, CubeState)> = lines + .enumerate() + .map(|(y, l)| { + l.chars() + .enumerate() + .map(|(x, c)| match c { + '#' => (x as i32, y as i32, 0, 0, CubeState::Active), + '.' => (x as i32, y as i32, 0, 0, CubeState::Inactive), + _ => panic!("Unknown State: {}", c), + }) + .collect::>() + }) + .fold(Vec::new(), |mut acc, mut x| { + acc.append(&mut x); + acc + }); + + for (x, y, z, w, s) in initial_slice { + world.insert((x, y, z, w), s); + } + + for _ in 0..6 { + let mut used_positions: HashSet<(i32, i32, i32, i32)> = HashSet::new(); + for (x, y, z, w) in world.keys() { + for coords in enumerate_adjacent(*x, *y, *z, *w) { + used_positions.insert(coords); + } + } + + let mut new_world: HashMap<(i32, i32, i32, i32), CubeState> = HashMap::new(); + for (x, y, z, w) in used_positions { + let cur_state = if let Some(state) = world.get(&(x, y, z, w)) { + *state + } else { + CubeState::Inactive + }; + + let active_adjacent = count_adjacent_active(x, y, z, w, &world); + + if cur_state == CubeState::Active && (active_adjacent == 2 || active_adjacent == 3) { + new_world.insert((x, y, z, w), CubeState::Active); + } else if cur_state == CubeState::Inactive && active_adjacent == 3 { + new_world.insert((x, y, z, w), CubeState::Active); + } else { + new_world.insert((x, y, z, w), CubeState::Inactive); + }; + } + + world = new_world; + } + + let active_count = world + .values() + .map(|s| match s { + CubeState::Active => 1, + _ => 0, + }) + .fold(0, |acc, x| x + acc); + + println!("Active Cells: {}", active_count); + + Ok(()) +}