generated from janezicmatej/aoc-template
perf: flatten Grid inner repr to Vec<u8>
This commit is contained in:
parent
0000020047
commit
000002103d
|
@ -8,25 +8,45 @@ use super::Point;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Grid {
|
pub struct Grid {
|
||||||
grid: Vec<Vec<u8>>,
|
grid: Vec<u8>,
|
||||||
|
width: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Grid {
|
impl FromStr for Grid {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let grid = s.lines().map(|x| x.as_bytes().to_vec()).collect();
|
let mut grid = Vec::with_capacity(s.len());
|
||||||
Ok(Self { grid })
|
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 {
|
impl Display for Grid {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
for row in self.grid.iter() {
|
for (idx, cell) in self.grid.iter().enumerate() {
|
||||||
for cell in row.iter() {
|
|
||||||
write!(f, "{}", *cell as char)?;
|
write!(f, "{}", *cell as char)?;
|
||||||
}
|
if idx > 0 && idx % self.width == 0 {
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,33 +54,33 @@ impl Display for Grid {
|
||||||
impl Index<Point> for Grid {
|
impl Index<Point> for Grid {
|
||||||
type Output = u8;
|
type Output = u8;
|
||||||
fn index(&self, index: Point) -> &Self::Output {
|
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 {
|
impl IndexMut<Point> for Grid {
|
||||||
fn index_mut(&mut self, index: Point) -> &mut Self::Output {
|
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 {
|
impl Grid {
|
||||||
pub fn find(&self, f: u8) -> Option<Point> {
|
pub fn find(&self, f: u8) -> Option<Point> {
|
||||||
let (i, j, _) = self
|
let n = self
|
||||||
.grid
|
.grid
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(i, x)| x.iter().copied().enumerate().map(move |(j, y)| (i, j, y)))
|
.find(|&(_, &x)| x == f)
|
||||||
.find(|x| x.2 == 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> {
|
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> {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue