diff options
-rw-r--r-- | 17/Cargo.toml | 11 | ||||
-rw-r--r-- | 17/input | 8 | ||||
-rw-r--r-- | 17/input.small | 3 | ||||
-rw-r--r-- | 17/src/main.rs | 249 | ||||
-rw-r--r-- | 17/tests/main.rs | 14 | ||||
-rw-r--r-- | Cargo.lock | 8 | ||||
-rw-r--r-- | Cargo.nix | 35 | ||||
-rw-r--r-- | Cargo.toml | 1 |
8 files changed, 329 insertions, 0 deletions
diff --git a/17/Cargo.toml b/17/Cargo.toml new file mode 100644 index 0000000..5bd32e3 --- /dev/null +++ b/17/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "advent_17" +version = "0.1.0" +authors = ["Irene Knapp <ireneista@gmail.com>"] +edition = "2018" + +[dependencies] +advent_lib = { path = "../lib" } + +[dev-dependencies] +assert_cmd = "0.10" diff --git a/17/input b/17/input new file mode 100644 index 0000000..c73e802 --- /dev/null +++ b/17/input @@ -0,0 +1,8 @@ +..#....# +##.#..## +.###.... +#....#.# +#.###### +##.#.... +#....... +.#...... diff --git a/17/input.small b/17/input.small new file mode 100644 index 0000000..eedd3d2 --- /dev/null +++ b/17/input.small @@ -0,0 +1,3 @@ +.#. +..# +### 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<bool>> = 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<Vec<bool>>, 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<Vec<bool>>, max_iterations: usize, use_w: bool) + -> Vec<Vec<Vec<Vec<bool>>>> +{ + let initial_height = initial_state.len(); + let initial_width = initial_state[0].len(); + + let mut hyperspace: Vec<Vec<Vec<Vec<bool>>>> = 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<Vec<Vec<Vec<bool>>>>, use_w: bool) + -> Vec<Vec<Vec<Vec<bool>>>> +{ + 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<Vec<Vec<Vec<bool>>>>) -> 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<Vec<Vec<Vec<bool>>>>, 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); +} + diff --git a/17/tests/main.rs b/17/tests/main.rs new file mode 100644 index 0000000..394fb0f --- /dev/null +++ b/17/tests/main.rs @@ -0,0 +1,14 @@ +use assert_cmd::prelude::*; +use std::process::Command; + + +#[test] +fn personal_input() -> Result<(), Box<dyn std::error::Error>> { + let mut command = Command::cargo_bin("advent_17")?; + + command.arg("input"); + command.assert().success().stdout("265\n1936\n"); + + Ok(()) +} + diff --git a/Cargo.lock b/Cargo.lock index 4bad3d1..38f47ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,6 +131,14 @@ dependencies = [ ] [[package]] +name = "advent_17" +version = "0.1.0" +dependencies = [ + "advent_lib", + "assert_cmd", +] + +[[package]] name = "advent_lib" version = "0.1.0" diff --git a/Cargo.nix b/Cargo.nix index c2d0abb..dbb1ed7 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -188,6 +188,16 @@ rec { # File a bug if you depend on any for non-debug work! debug = internal.debugCrate { inherit packageId; }; }; + "advent_17" = rec { + packageId = "advent_17"; + build = internal.buildRustCrateWithFeatures { + packageId = "advent_17"; + }; + + # Debug support which might change between releases. + # File a bug if you depend on any for non-debug work! + debug = internal.debugCrate { inherit packageId; }; + }; "advent_lib" = rec { packageId = "advent_lib"; build = internal.buildRustCrateWithFeatures { @@ -628,6 +638,31 @@ rec { ]; }; + "advent_17" = rec { + crateName = "advent_17"; + version = "0.1.0"; + edition = "2018"; + crateBin = [ + { name = "advent_17"; path = "src/main.rs"; } + ]; + src = (builtins.filterSource sourceFilter ./17); + authors = [ + "Irene Knapp <ireneista@gmail.com>" + ]; + dependencies = [ + { + name = "advent_lib"; + packageId = "advent_lib"; + } + ]; + devDependencies = [ + { + name = "assert_cmd"; + packageId = "assert_cmd"; + } + ]; + + }; "advent_lib" = rec { crateName = "advent_lib"; version = "0.1.0"; diff --git a/Cargo.toml b/Cargo.toml index 4a97c58..c2dfe1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,5 @@ members = [ "14", "15", "16", + "17", ] |