From 04dcd76a2275f80a1da558bb4e497f3c4577412f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Mon, 14 Dec 2020 15:31:05 +0000 Subject: [PATCH] WIP: Re-implement using ndarray --- day-11/Cargo.lock | 80 +++++++++++++++--------- day-11/Cargo.toml | 2 +- day-11/src/main.rs | 148 ++++++++++++++++----------------------------- 3 files changed, 105 insertions(+), 125 deletions(-) diff --git a/day-11/Cargo.lock b/day-11/Cargo.lock index 097af7b..edc61df 100644 --- a/day-11/Cargo.lock +++ b/day-11/Cargo.lock @@ -11,29 +11,7 @@ name = "day-11" version = "0.1.0" dependencies = [ "indoc", - "petgraph", -] - -[[package]] -name = "fixedbitset" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" - -[[package]] -name = "hashbrown" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" - -[[package]] -name = "indexmap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" -dependencies = [ - "autocfg", - "hashbrown", + "ndarray", ] [[package]] @@ -60,13 +38,53 @@ dependencies = [ ] [[package]] -name = "petgraph" -version = "0.5.1" +name = "matrixmultiply" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +checksum = "916806ba0031cd542105d916a97c8572e1fa6dd79c9c51e7eb43a09ec2dd84c1" dependencies = [ - "fixedbitset", - "indexmap", + "rawpointer", +] + +[[package]] +name = "ndarray" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c0d5c9540a691d153064dc47a4db2504587a75eae07bf1d73f7a596ebc73c04" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "rawpointer", +] + +[[package]] +name = "num-complex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", ] [[package]] @@ -93,6 +111,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "syn" version = "1.0.54" diff --git a/day-11/Cargo.toml b/day-11/Cargo.toml index 115407c..1a7f7d8 100644 --- a/day-11/Cargo.toml +++ b/day-11/Cargo.toml @@ -8,4 +8,4 @@ edition = "2018" [dependencies] indoc = "0.3" -petgraph = "0.5" +ndarray = "0.14" diff --git a/day-11/src/main.rs b/day-11/src/main.rs index 813bb24..cc2c6ac 100644 --- a/day-11/src/main.rs +++ b/day-11/src/main.rs @@ -1,32 +1,24 @@ use std::fs; +use std::iter; -use petgraph::graph::{DiGraph, Graph}; -use petgraph::visit::IntoNodeIdentifiers; +use ndarray::Array2; fn main() -> Result<(), Box> { let input = fs::read_to_string("input")?; let layout = parse_layout(&input)?; // Part 1 - let result = count_eventually_occupied_seats(&layout); + let result = count_with_neighboring_seats(&layout); + println!("{}", result); + + // Part 2 + let result = count_with_directional_seats(&layout); println!("{}", result); Ok(()) } -type Layout = DiGraph; - -#[derive(Copy, Clone, Debug)] -enum Direction { - NorthWest, - North, - NorthEast, - West, - East, - SouthWest, - South, - SouthEast, -} +type Layout = Array2; #[derive(Copy, Clone, Debug, PartialEq)] enum Seating { @@ -47,92 +39,33 @@ impl Seating { } fn parse_layout(input: &str) -> Result { - let mut output: Layout = Graph::new(); + let (i, j) = ( + input.lines().count(), + input.lines().next().ok_or("Waiting room too small")?.len(), + ); - let grid: Vec> = input + // Padding the input data so that we can later comfortably produce + // a convolution + + let grid = input .lines() - .map(|line| { - line.chars() - .map(|c| Ok(output.add_node(Seating::new(c)?))) - .collect() + .flat_map(|line| { + iter::once(Ok(Seating::Floor)) + .chain(line.chars().map(Seating::new)) + .chain(iter::once(Ok(Seating::Floor))) }) - .collect::>()?; + .collect::, String>>()?; - for i in 0..grid.len() { - for j in 0..grid[0].len() { - if let Some(node) = grid.get(i).and_then(|row| row.get(j)) { - for ((c, r), direction) in [ - ((0, 0), Direction::NorthWest), - ((0, 1), Direction::North), - ((0, 2), Direction::NorthEast), - ((1, 0), Direction::West), - ((1, 2), Direction::East), - ((2, 0), Direction::SouthWest), - ((2, 1), Direction::South), - ((2, 2), Direction::SouthEast), - ] - .iter() - { - if let (Some(c), Some(r)) = ((i + c).checked_sub(1), (j + r).checked_sub(1)) { - if let Some(target) = grid.get(c).and_then(|row| row.get(r)) { - output.add_edge(*node, *target, *direction); - } - } - } - } - } - } - - Ok(output) + Array2::from_shape_vec((i, j), grid) + .map_err(|_| "Non-square waiting rooms don't exist".to_string()) } -fn count_eventually_occupied_seats(layout: &Layout) -> usize { - let mut layout = layout.clone(); +fn count_with_neighboring_seats(layout: &Layout) -> usize { + unimplemented!() +} - loop { - let mut changes = 0; - - layout = layout.map( - |node, seat| match seat { - Seating::Occupied => { - if layout - .neighbors(node) - .filter(|seat| layout[*seat] == Seating::Occupied) - .count() - >= 4 - { - changes += 1; - Seating::Empty - } else { - *seat - } - } - Seating::Empty => { - if !layout - .neighbors(node) - .any(|seat| layout[seat] == Seating::Occupied) - { - changes += 1; - Seating::Occupied - } else { - *seat - } - } - Seating::Floor => Seating::Floor, - }, - |_, direction| *direction, - ); - - if changes == 0 { - break; - } - } - - layout - .node_identifiers() - .map(|id| layout[id]) - .filter(|seat| *seat == Seating::Occupied) - .count() +fn count_with_directional_seats(layout: &Layout) -> usize { + unimplemented!() } #[cfg(test)] @@ -157,7 +90,30 @@ mod tests { ); let layout = parse_layout(&input)?; - let result = count_eventually_occupied_seats(&layout); + let result = count_with_neighboring_seats(&layout); + + assert_eq!(result, 37); + Ok(()) + } + + #[test] + fn test_simple2() -> Result<(), Box> { + let input = indoc!( + "L.LL.LL.LL + LLLLLLL.LL + L.L.L..L.. + LLLL.LL.LL + L.LL.LL.LL + L.LLLLL.LL + ..L.L..... + LLLLLLLLLL + L.LLLLLL.L + L.LLLLL.LL + " + ); + + let layout = parse_layout(&input)?; + let result = count_with_directional_seats(&layout); assert_eq!(result, 37); Ok(())