From 806f86214ba764773c466ed66a8964a8bc880168 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Fri, 11 Dec 2020 10:13:12 -0800 Subject: [PATCH] Day 11. Sigh. --- inputs/day11.txt | 97 +++++++++++++++++++++++++++ inputs/day11_test1.txt | 10 +++ src/bin/ferry.rs | 115 +++++++++++++++++++++++++++++++ src/errors.rs | 10 +++ src/map.rs | 149 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 374 insertions(+), 7 deletions(-) create mode 100644 inputs/day11.txt create mode 100644 inputs/day11_test1.txt create mode 100644 src/bin/ferry.rs diff --git a/inputs/day11.txt b/inputs/day11.txt new file mode 100644 index 0000000..bbaf4ea --- /dev/null +++ b/inputs/day11.txt @@ -0,0 +1,97 @@ +LLLLLLLLL.L.LLL.L.LLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLL.LLLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LLL.LLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL +L..LL.L.L....L..L.L....L.....L.L.L......L..L..L....L.LL.......L.....L....L..L................L.... +LLLLLLLLLLLLLLL.LLL.LLL.LLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL..LLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLL.LLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL +LL.LLLLLLLLLLLL.LLL.LLL.LLLLLLLL.LLLLLLLL.LLLLLLL..LLLL.LLLLLLL.LLLL.LLLLLL.LLLLL.LLLL.LL.LLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLL.L.LLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLL.LLLLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL.LL.LLLLLLLLLLLLLLLL +.LLLL..L.L..L....L.LLL...LLL..L.L....L.L.L...L.....L...L.....L...L..L...LL...L..LLL..L...L....L..L +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLL.LLLL..LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL..LLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +.....LL...LL..L...L..L..LL.L..LLL...L..L.LLL...LLL..L.....L...L.....L........LLLL..LLL.....L....L. +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LL +LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLL.LL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLL.L +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLL.LLLLLLLLL.LLLLLLL.LLLL.LLL.LL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLL.LLLLLLLL +....L..LL.L.L......L..LL.......LL......L..L...L..L.........LL....LL.LLL..LLLL..L..L.......L....L.. +LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLL.LLL.L.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLL.LLLLLLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL +.LL..LLLLL.LL.L...L...L...L....LLLL...LLLL.LL...LL...L.LL...LL..LL.L..L......L....L.L.L.L...LL...L +LLLLLLLLL.LLLLLLLLLLLLL..LLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLLLLL.LL.LLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLL.L.LLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLL..LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LL.LL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLL.LLLLL.L.LLLLLLLL +....L.........LL...L.L..LL.L.L..L......L.L.L...L....L.......LL.LL....L.L...L....L...L....L...L.... +L.LLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLL.LL..LLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLL..LLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.L.LLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLL.LL.LLLLLLLLLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LLL..L.L........L...L..L.LLLLLLL..LLLL..L...L..L.L..LLL....L..L.LLL..L...L..L.......L.LLLLLL.LL.L. +LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLL.LL.LLLL.LLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LL.LL.LLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL +L...L.....LL....L.L.LLLLL.....L....LL..L.....L...L.L.LL.......LL...LL............L.L..L..LLL..LL.. +LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLL.LLLLL.LLLLLLL.LLLLL.LL +LL.LLLLLLLLLLLL.L.LLL.LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LL.LLLL.LLLLLL.LLLLL.LLLLLLL.L.LLLLLL +LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLL.LLLL +LLLLLLLLL.LLLLL.L.LLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLL +LLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLL.LLLLLL..LLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LL...L.........L..LLL........L.L..L....L.L.L....LLLL.LL.L....LL....L.LL.LLL..L..L....LL.L......LLL +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLL.L.LLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL +...L........L....L.L.LL.LL.L.L.....L.L..L.....LL....L..L.L.L..L..L.L...L.........L.LL.LLLLL..L.... +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLL..LLLL.LLLLLLL.LLLLLLLLLLL.LLL.L.LLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.L.LLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLL.LL.LLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLL..LLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL +..LLLL.L..LL.L......LL.L...L.L..L....LLL.........L....L.......LL.LLL.L.L.....LL.L...L.LLL....L.... +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.L.LLL.LLLLLLL.LLLL.LLLLLL.LLLL..LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.L.LLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLLLLLLL.LL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LL...LLLLL.....LL..L.....L....L......L.L........LL......LL.LL..L..LLL.L...L..L..L.L.....LLLL...LLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLL.LLLLL.LLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLL +.LL..L.....LLLL.LL..L.LL....L.LL...L..LL......L..LL...LL..L.L.LLLL...LL.L..L..LLL.L.L.....L.LL.LL. +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLL.LL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLL.LLLL.LLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLL.LL +LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL.LLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLL.L.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL diff --git a/inputs/day11_test1.txt b/inputs/day11_test1.txt new file mode 100644 index 0000000..ff5431a --- /dev/null +++ b/inputs/day11_test1.txt @@ -0,0 +1,10 @@ +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 \ No newline at end of file diff --git a/src/bin/ferry.rs b/src/bin/ferry.rs new file mode 100644 index 0000000..c9317ce --- /dev/null +++ b/src/bin/ferry.rs @@ -0,0 +1,115 @@ +use advent2020::errors::{MapOperationError, MapParseError, TopLevelError}; +use advent2020::map::Map; +use std::convert::TryFrom; +use std::env; +use std::fs; + +#[derive(Clone, Debug, Eq, PartialEq)] +enum FerryLocation { + Floor, + EmptySeat, + TakenSeat, +} + +impl FerryLocation { + fn is_seat(&self) -> bool { + self != &FerryLocation::Floor + } +} + +impl TryFrom for FerryLocation { + type Error = MapParseError; + + fn try_from(c: char) -> Result { + match c { + '.' => Ok(FerryLocation::Floor), + 'L' => Ok(FerryLocation::EmptySeat), + '#' => Ok(FerryLocation::TakenSeat), + _ => Err(MapParseError::UnexpectedCharacter(c)), + } + } +} + +impl Into for FerryLocation { + fn into(self) -> char { + match self { + FerryLocation::Floor => '.', + FerryLocation::EmptySeat => 'L', + FerryLocation::TakenSeat => '#', + } + } +} + +struct EvolvingMap { + next_map: Option>, + occupation_tolerance: usize, + view: fn(&Map, usize, usize) -> Result, MapOperationError>, +} + +impl From> for EvolvingMap { + fn from(start_map: Map) -> EvolvingMap { + EvolvingMap { + next_map: Some(start_map), + occupation_tolerance: 4, + view: |m, x, y| { m.adjacents(x, y) }, + } + } +} + +impl Iterator for EvolvingMap { + type Item = Map; + + fn next(&mut self) -> Option { + let current_map = self.next_map.clone()?; + let mut next_map = current_map.clone(); + + for (x, y, value) in current_map.locations() { + let occupied_neighbors = (self.view)(¤t_map, x, y).ok()?.iter().filter(|x| **x == FerryLocation::TakenSeat).count(); + match value { + FerryLocation::EmptySeat if occupied_neighbors == 0 => { + next_map.set(x, y, FerryLocation::TakenSeat).ok()?; + } + FerryLocation::TakenSeat if occupied_neighbors >= self.occupation_tolerance => { + next_map.set(x, y, FerryLocation::EmptySeat).ok()?; + } + _ => {} + } + } + + if next_map == current_map { + self.next_map = None; + } else { + self.next_map = Some(next_map); + } + + Some(current_map) + } +} + +fn main() -> Result<(),TopLevelError> { + let filename = env::args().nth(1).expect("No file argument given."); + let contents = fs::read_to_string(filename)?; + let map = Map::::try_from(contents.as_str())?; + + // part 1 + let base_evolving_map = EvolvingMap::from(map.clone()); + for (idx, step) in base_evolving_map.enumerate() { + println!("Base map, step #{}", idx); + step.print(); + println!("# of occupied seats: {}\n", step.count(FerryLocation::TakenSeat)); + } + + // part 2 + let view_evolving_map = EvolvingMap { + next_map: Some(map), + occupation_tolerance: 5, + view: |m,x,y| m.adjacents_until(x, y, FerryLocation::is_seat), + }; + for (idx, step) in view_evolving_map.enumerate() { + println!("Extended map, step #{}", idx); + step.print(); + println!("# of occupied seats: {}\n", step.count(FerryLocation::TakenSeat)); + } + + Ok(()) +} \ No newline at end of file diff --git a/src/errors.rs b/src/errors.rs index 67491a8..6edabca 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -42,6 +42,10 @@ pub enum TopLevelError { }, #[error("Numeric conversion error: {0}")] NumConversionError(#[from] ParseIntError), + #[error("Error parsing map: {0}")] + MapParseError(#[from] MapParseError), + #[error("Error accessing map: {0}")] + MapOperationError(#[from] MapOperationError), } #[derive(Error, Debug)] @@ -130,3 +134,9 @@ pub enum ExecutionError { #[error("Tried to execute non-existent instruction at {0}")] NonExistentLocation(isize), } + +#[derive(Error, Debug)] +pub enum MapOperationError { + #[error("Out of bounds indexing map with ({0},{1})")] + OutOfBounds(usize, usize), +} \ No newline at end of file diff --git a/src/map.rs b/src/map.rs index 8715cb5..7c94409 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,9 +1,10 @@ -use crate::errors::MapParseError; -use std::convert::TryFrom; +use crate::errors::{MapOperationError, MapParseError}; +use std::convert::{Into, TryFrom}; +#[derive(Clone)] pub struct Map { width: usize, - _height: usize, + height: usize, data: Vec>, } @@ -16,7 +17,7 @@ where fn try_from(s: &str) -> Result, E> { let mut width = 0; - let mut _height = 0; + let mut height = 0; let mut data = Vec::new(); for line in s.lines() { @@ -27,18 +28,18 @@ where current_line.push(item); } - _height += 1; + height += 1; if width == 0 { width = current_line.len(); } else if width != current_line.len() { - return Err(E::from(MapParseError::UnevenLines(_height))); + return Err(E::from(MapParseError::UnevenLines(height))); } data.push(current_line); } Ok(Map { width, - _height, + height, data, }) } @@ -50,4 +51,138 @@ impl Map { let wrapped_x = x % self.width; Some(row[wrapped_x].clone()) } + + pub fn at_unwrapped(&self, x: usize, y: usize) -> Option { + let row = self.data.get(y)?; + row.get(x).map(|x| x.clone()) + } + + fn view(&self, f: fn(&X) -> bool, x: usize, y: usize, rise: isize, run: isize) -> Option { + let mut sx = (x as isize) + run; + let mut sy = (y as isize) + rise; + + loop { + if sx < 0 { return None; } + if sy < 0 { return None; } + + let entry = self.at_unwrapped(sx as usize, sy as usize)?; + if f(&entry) { + return Some(entry) + } + + sx += run; + sy += rise; + } + } + + pub fn set(&mut self, x: usize, y: usize, value: X) -> Result<(), MapOperationError> { + let row = self.data.get_mut(y).ok_or(MapOperationError::OutOfBounds(x, y))?; + + if x >= self.width { + return Err(MapOperationError::OutOfBounds(x, y)); + } + + row[x] = value; + + Ok(()) + } + + pub fn adjacents(&self, x: usize, y: usize) -> Result, MapOperationError> { + self.adjacents_until(x, y, |_| true) + } + + pub fn adjacents_until(&self, x: usize, y: usize, f: fn(&X) -> bool) -> Result, MapOperationError> + { + if y >= self.height { + return Err(MapOperationError::OutOfBounds(x, y)); + } + + if x >= self.width { + return Err(MapOperationError::OutOfBounds(x, y)); + } + + let mut results = Vec::new(); + push_some(&mut results, self.view(f, x, y, -1, -1)); + push_some(&mut results, self.view(f, x, y, -1, -0)); + push_some(&mut results, self.view(f, x, y, -1, 1)); + push_some(&mut results, self.view(f, x, y, -0, -1)); + push_some(&mut results, self.view(f, x, y, -0, 1)); + push_some(&mut results, self.view(f, x, y, 1, -1)); + push_some(&mut results, self.view(f, x, y, 1, 0)); + push_some(&mut results, self.view(f, x, y, 1, 1)); + + + Ok(results) + } + + pub fn locations<'a>(&'a self) -> MapLocations<'a, X> { + MapLocations { + underlying: self, + x: 0, + y: 0, + } + } } + +impl Map { + pub fn count(&self, x: X) -> usize { + self.locations().filter(|v| v.2 == x).count() + } +} + +pub struct MapLocations<'a,X: Clone> { + underlying: &'a Map, + x: usize, + y: usize, +} + +impl<'a, X: Clone> Iterator for MapLocations<'a,X> { + type Item = (usize, usize, X); + + fn next(&mut self) -> Option { + loop { + if (self.x == self.underlying.width) && (self.y == self.underlying.height) { + return None; + } + + if self.x == self.underlying.width { + self.x = 0; + self.y += 1; + continue; + } + + let value = self.underlying.at_unwrapped(self.x, self.y)?; + let result = (self.x, self.y, value); + self.x += 1; + + return Some(result); + } + } +} + +impl> Map { + pub fn print(&self) { + for y in 0..self.height { + for x in 0..self.width { + print!("{}", self.at(x, y).unwrap().into()); + } + println!(""); + } + } +} + +impl PartialEq> for Map { + fn eq(&self, other: &Self) -> bool { + self.height == other.height && + self.width == other.width && + self.data == other.data + } +} + +impl Eq for Map { } + +fn push_some(vector: &mut Vec, value: Option) { + if let Some(val) = value { + vector.push(val); + } +} \ No newline at end of file