From 000002103d21c0e32b023375fa47eec3e5df8f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Mon, 16 Dec 2024 21:57:13 +0100 Subject: [PATCH] perf: flatten Grid inner repr to Vec --- src/grid_vec/grid.rs | 50 +++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/grid_vec/grid.rs b/src/grid_vec/grid.rs index a734684..65e374b 100644 --- a/src/grid_vec/grid.rs +++ b/src/grid_vec/grid.rs @@ -8,24 +8,44 @@ use super::Point; #[derive(Debug, Clone)] pub struct Grid { - grid: Vec>, + grid: Vec, + width: usize, } impl FromStr for Grid { type Err = (); fn from_str(s: &str) -> Result { - let grid = s.lines().map(|x| x.as_bytes().to_vec()).collect(); - Ok(Self { grid }) + let mut grid = Vec::with_capacity(s.len()); + let mut width = None; + + for line in s.lines() { + let w = line.len(); + + if width.is_none() { + width = Some(w); + } + + if width.filter(|&x| x == w).is_none() { + panic!("all lines have to be of same length"); + } + + grid.extend(line.bytes()); + } + + Ok(Self { + grid, + width: width.unwrap(), + }) } } impl Display for Grid { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - for row in self.grid.iter() { - for cell in row.iter() { - write!(f, "{}", *cell as char)?; + for (idx, cell) in self.grid.iter().enumerate() { + write!(f, "{}", *cell as char)?; + if idx > 0 && idx % self.width == 0 { + writeln!(f)?; } - writeln!(f)?; } Ok(()) } @@ -34,33 +54,33 @@ impl Display for Grid { impl Index for Grid { type Output = u8; fn index(&self, index: Point) -> &Self::Output { - &self.grid[index.i][index.j] + &self.grid[index.i * self.width + index.j] } } impl IndexMut for Grid { fn index_mut(&mut self, index: Point) -> &mut Self::Output { - &mut self.grid[index.i][index.j] + &mut self.grid[index.i * self.width + index.j] } } impl Grid { pub fn find(&self, f: u8) -> Option { - let (i, j, _) = self + let n = self .grid .iter() .enumerate() - .flat_map(|(i, x)| x.iter().copied().enumerate().map(move |(j, y)| (i, j, y))) - .find(|x| x.2 == f)?; + .find(|&(_, &x)| x == f) + .map(|x| x.0)?; - Some(Point::new(i, j)) + Some(Point::new(n / self.width, n % self.width)) } pub fn get(&self, p: &Point) -> Option<&u8> { - self.grid.get(p.i).and_then(|r| r.get(p.j)) + self.grid.get(p.i * self.width + p.j) } pub fn get_mut(&mut self, p: &Point) -> Option<&mut u8> { - self.grid.get_mut(p.i).and_then(|r| r.get_mut(p.j)) + self.grid.get_mut(p.i * self.width + p.j) } }