Improve tick performance in game_of_life

This commit is contained in:
Héctor Ramón Jiménez 2020-05-01 01:24:31 +02:00
parent a6db1e1fb3
commit 377ead93d6

View File

@ -353,17 +353,19 @@ mod grid {
}
fn tick(&mut self) {
use itertools::Itertools;
let mut adjacent_life = HashMap::new();
let populated_neighbors: HashMap<Cell, usize> = self
.cells
.iter()
.flat_map(Cell::cluster)
.unique()
.map(|cell| (cell, self.count_adjacent(cell)))
.collect();
for cell in &self.cells {
let _ = adjacent_life.entry(*cell).or_insert(0);
for (cell, amount) in populated_neighbors.iter() {
for neighbor in Cell::neighbors(*cell) {
let amount = adjacent_life.entry(neighbor).or_insert(0);
*amount += 1;
}
}
for (cell, amount) in adjacent_life.iter() {
match amount {
2 => {}
3 => {
@ -375,17 +377,6 @@ mod grid {
}
}
}
fn count_adjacent(&self, cell: Cell) -> usize {
let cluster = Cell::cluster(&cell);
let is_neighbor = |candidate| candidate != cell;
let is_populated = |cell| self.cells.contains(&cell);
cluster
.filter(|&cell| is_neighbor(cell) && is_populated(cell))
.count()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -407,7 +398,7 @@ mod grid {
}
}
fn cluster(cell: &Cell) -> impl Iterator<Item = Cell> {
fn cluster(cell: Cell) -> impl Iterator<Item = Cell> {
use itertools::Itertools;
let rows = cell.i.saturating_sub(1)..=cell.i.saturating_add(1);
@ -416,6 +407,10 @@ mod grid {
rows.cartesian_product(columns).map(|(i, j)| Cell { i, j })
}
fn neighbors(cell: Cell) -> impl Iterator<Item = Cell> {
Cell::cluster(cell).filter(move |candidate| *candidate != cell)
}
fn all_visible_in(region: Rectangle) -> impl Iterator<Item = Cell> {
use itertools::Itertools;