diff --git a/day11/src/main.rs b/day11/src/main.rs index 44fa209..0b5469e 100644 --- a/day11/src/main.rs +++ b/day11/src/main.rs @@ -7,15 +7,16 @@ mod board_metadata; mod game; mod rules; mod rules_easy; +mod rules_hard; use binary::State; use game::Game; +use rules::Rules; use rules_easy::RulesEasy; +use rules_hard::RulesHard; -fn main() { - let stdin = io::stdin(); - let lines: Vec<_> = stdin.lock().lines().map(|line| line.unwrap()).collect(); - let mut game = Game::from_input::(&lines); +fn solve(lines: &[String]) { + let mut game = Game::from_input::(&lines); //game.print_board(); @@ -31,3 +32,11 @@ fn main() { game.print_board(); println!("Board stabilized at {} occupied seats", game.get_count_of_cells_for_state(State::SeatOccupied)); } + +fn main() { + let stdin = io::stdin(); + let lines: Vec<_> = stdin.lock().lines().map(|line| line.unwrap()).collect(); + + solve::(&lines); + solve::(&lines); +} diff --git a/day11/src/rules_hard.rs b/day11/src/rules_hard.rs new file mode 100644 index 0000000..dc2a6ff --- /dev/null +++ b/day11/src/rules_hard.rs @@ -0,0 +1,47 @@ +use enum_map::EnumMap; +use ndarray::Array2; +use strum::IntoEnumIterator; +use crate::binary::{Direction, State}; +use crate::board_metadata::{BoardMetadata,CellLocation}; +use crate::rules::Rules; + +fn find_neighbour(cell_location: CellLocation, direction: Direction, board_metadata: &BoardMetadata, original_states: &Array2) -> Option { + let mut location = cell_location; + loop { + match board_metadata.get_neighbour_location(location, direction) { + Some(new_location) => match original_states[new_location] { + State::SeatEmpty | State::SeatOccupied => { + return Some(new_location); + }, + _ => { + location = new_location; + }, + }, + None => { + return None; + }, + } + } +} + +pub struct RulesHard {} + +impl Rules for RulesHard { + fn get_next_state(current_state: State, neighbour_counts: EnumMap) -> State { + match current_state { + State::SeatEmpty => if neighbour_counts[State::SeatOccupied] == 0 { State::SeatOccupied } else { State::SeatEmpty }, + State::SeatOccupied => if neighbour_counts[State::SeatOccupied] >= 5 { State::SeatEmpty } else { State::SeatOccupied }, + other => other + } + } + + fn get_neighbours(cell_location: CellLocation, board_metadata: &BoardMetadata, original_states: &Array2) -> EnumMap> { + let mut neighbours = EnumMap::new(); + + for direction in Direction::iter() { + neighbours[direction] = find_neighbour(cell_location, direction, &board_metadata, &original_states) + } + + neighbours + } +}