From 9acefe571def801d63282620cb31833a321bc551 Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Wed, 16 Dec 2020 22:47:29 -0800 Subject: 17 --- 17/src/main.rs | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 17/src/main.rs (limited to '17/src') diff --git a/17/src/main.rs b/17/src/main.rs new file mode 100644 index 0000000..9924b02 --- /dev/null +++ b/17/src/main.rs @@ -0,0 +1,249 @@ +use advent_lib::prelude::*; + +use std::convert::TryFrom; + + +fn main() -> Result<()> { + let mut args = std::env::args(); + if args.len() != 2 { + eprintln!("Usage: advent input"); + } + let _ = args.next(); + let filename = args.next().unwrap(); + + let input = advent_lib::read_lines_file(&filename)?; + let input = advent_lib::group_lines_by_blanks(input); + + let mut initial_state: Vec> = Vec::new(); + + for line in &input[0] { + let mut row = Vec::new(); + for c in line.chars() { + if c == '#' { + row.push(true); + } else { + row.push(false); + } + } + initial_state.push(row); + } + + do_4d(&initial_state, false); + do_4d(&initial_state, true); + + Ok(()) +} + + +fn do_4d(initial_state: &Vec>, use_w: bool) { + let max_iterations = 6; + + let mut hyperspace = init_4d(initial_state, max_iterations, use_w); + + for _ in 0 .. max_iterations { + hyperspace = step_4d(&hyperspace, use_w); + } + + let active_count = count_active_4d(&hyperspace); + println!("{}", active_count); +} + + +fn init_4d(initial_state: &Vec>, max_iterations: usize, use_w: bool) + -> Vec>>> +{ + let initial_height = initial_state.len(); + let initial_width = initial_state[0].len(); + + let mut hyperspace: Vec>>> = Vec::new(); + for w in 0 .. max_iterations * 2 + 1 { + if w > 0 && !use_w { + continue; + } + + let mut space = Vec::new(); + for z in 0 .. max_iterations * 2 + 1 { + let mut plane = Vec::new(); + for y in 0 .. initial_height + max_iterations * 2 + 1 { + let y_shifted = isize::try_from(y).unwrap() + - isize::try_from(max_iterations).unwrap(); + + let mut row = Vec::new(); + for x in 0 .. initial_width + max_iterations * 2 + 1 { + let x_shifted = isize::try_from(x).unwrap() + - isize::try_from(max_iterations).unwrap(); + + if ((use_w && w == max_iterations) || (!use_w && w == 0)) + && z == max_iterations + && y_shifted >= 0 && y_shifted < isize::try_from(initial_height).unwrap() + && x_shifted >= 0 && x_shifted < isize::try_from(initial_width).unwrap() + { + row.push(initial_state[usize::try_from(y_shifted).unwrap()] + [usize::try_from(x_shifted).unwrap()]); + } else { + row.push(false); + } + } + + plane.push(row); + } + + space.push(plane); + } + + hyperspace.push(space); + } + + hyperspace +} + + +fn step_4d(input_hyperspace: &Vec>>>, use_w: bool) + -> Vec>>> +{ + let mut output_hyperspace = Vec::new(); + + for w in 0 .. input_hyperspace.len() { + if w > 0 && !use_w { + continue; + } + + let input_space = &input_hyperspace[w]; + let mut output_space = Vec::new(); + + for z in 0 .. input_space.len() { + let input_plane = &input_space[z]; + let mut output_plane = Vec::new(); + + for y in 0 .. input_plane.len() { + let input_row = &input_plane[y]; + let mut output_row = Vec::new(); + + for x in 0 .. input_row.len() { + let mut adjacent_count = 0; + + for dw in [-1, 0, 1].iter() { + for dz in [-1, 0, 1].iter() { + for dy in [-1, 0, 1].iter() { + for dx in [-1, 0, 1].iter() { + if *dw == 0 && *dz == 0 && *dy == 0 && *dx == 0 { + continue; + } + + let shifted_w = isize::try_from(w).unwrap() + dw; + let shifted_z = isize::try_from(z).unwrap() + dz; + let shifted_y = isize::try_from(y).unwrap() + dy; + let shifted_x = isize::try_from(x).unwrap() + dx; + + if shifted_w < 0 + || shifted_w >= isize::try_from(input_hyperspace.len()).unwrap() + { + continue; + } + if shifted_z < 0 + || shifted_z >= isize::try_from(input_space.len()).unwrap() + { + continue; + } + if shifted_y < 0 + || shifted_y >= isize::try_from(input_plane.len()).unwrap() + { + continue; + } + if shifted_x < 0 + || shifted_x >= isize::try_from(input_row.len()).unwrap() + { + continue; + } + + if input_hyperspace[usize::try_from(shifted_w).unwrap()] + [usize::try_from(shifted_z).unwrap()] + [usize::try_from(shifted_y).unwrap()] + [usize::try_from(shifted_x).unwrap()] + { + adjacent_count += 1; + } + } + } + } + } + + let mut output_cell = false; + + if input_row[x] { + if adjacent_count >= 2 && adjacent_count <= 3 { + output_cell = true; + } + } else { + if adjacent_count == 3 { + output_cell = true; + } + } + + output_row.push(output_cell); + } + + output_plane.push(output_row); + } + + output_space.push(output_plane); + } + + output_hyperspace.push(output_space); + } + + output_hyperspace +} + + +fn count_active_4d(hyperspace: &Vec>>>) -> usize { + let mut count = 0; + + for space in hyperspace { + for plane in space { + for row in plane { + for cell in row { + if *cell { + count += 1; + } + } + } + } + } + + count +} + + +pub fn debug_4d(hyperspace: &Vec>>>, use_w: bool) { + let mut output = String::new(); + + for w in 0 .. hyperspace.len() { + if w > 0 && !use_w { + continue; + } + + let space = &hyperspace[w]; + for z in 0 .. space.len() { + let plane = &space[z]; + + if w > 0 || z > 0 { + output.push_str("\n"); + } + output.push_str(&format!("w: {}, z: {}\n", w, z)); + + for row in plane { + for cell in row { + if *cell { + output.push_str("#"); + } else { + output.push_str("."); + } + } + output.push_str("\n"); + } + } + } + println!("{}", output); +} + -- cgit 1.4.1