perf: flatten Grid inner repr to Vec<u8>

This commit is contained in:
Matej Janezic 2024-12-16 21:57:13 +01:00
parent 0000020047
commit 000002103d
Signed by: janezicmatej
GPG Key ID: 4298E230ED37B2C0
1 changed files with 35 additions and 15 deletions

View File

@ -8,25 +8,45 @@ use super::Point;
#[derive(Debug, Clone)]
pub struct Grid {
grid: Vec<Vec<u8>>,
grid: Vec<u8>,
width: usize,
}
impl FromStr for Grid {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
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() {
for (idx, cell) in self.grid.iter().enumerate() {
write!(f, "{}", *cell as char)?;
}
if idx > 0 && idx % self.width == 0 {
writeln!(f)?;
}
}
Ok(())
}
}
@ -34,33 +54,33 @@ impl Display for Grid {
impl Index<Point> 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<Point> 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<Point> {
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)
}
}