2022 rust matrix draw_line
This commit is contained in:
parent
edc4447c7c
commit
b4dca1df8c
|
@ -27,7 +27,7 @@ fn mark_visible(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_mask(data: &Matrix<i32>) -> Matrix<bool> {
|
fn create_mask(data: &Matrix<i32>) -> Matrix<bool> {
|
||||||
let (rows, cols) = data.shape();
|
let (rows, cols) = data.get_shape();
|
||||||
let mut visible = Matrix::with_shape((rows, cols), false);
|
let mut visible = Matrix::with_shape((rows, cols), false);
|
||||||
|
|
||||||
for row in 0..rows {
|
for row in 0..rows {
|
||||||
|
@ -59,9 +59,9 @@ fn solve1(data: &Matrix<i32>) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_scores(data: &Matrix<i32>) -> Matrix<i32> {
|
fn find_scores(data: &Matrix<i32>) -> Matrix<i32> {
|
||||||
let mut scores = Matrix::with_shape(data.shape(), 1);
|
let mut scores = Matrix::with_shape(data.get_shape(), 1);
|
||||||
|
|
||||||
let (rows, cols) = data.shape();
|
let (rows, cols) = data.get_shape();
|
||||||
for (row, col) in data.cell_indices() {
|
for (row, col) in data.cell_indices() {
|
||||||
let mut score = 1;
|
let mut score = 1;
|
||||||
let current = data[(row, col)];
|
let current = data[(row, col)];
|
||||||
|
|
|
@ -59,7 +59,7 @@ fn a_star(start: (usize, usize), goal: (usize, usize), grid: &Matrix<u8>) -> Opt
|
||||||
while let Some(State { position: current, .. }) = frontier.pop() {
|
while let Some(State { position: current, .. }) = frontier.pop() {
|
||||||
if current == goal { break };
|
if current == goal { break };
|
||||||
|
|
||||||
for neighbour in neighbours(current, grid.shape()) {
|
for neighbour in neighbours(current, grid.get_shape()) {
|
||||||
// unreachable
|
// unreachable
|
||||||
let level_diff = grid[neighbour].abs_diff(grid[current]);
|
let level_diff = grid[neighbour].abs_diff(grid[current]);
|
||||||
if grid[neighbour] > grid[current] && level_diff > 1 { continue };
|
if grid[neighbour] > grid[current] && level_diff > 1 { continue };
|
||||||
|
|
|
@ -28,6 +28,7 @@ impl Display for Tile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn get_data_bounds(data: &[Vec<(usize, usize)>]) -> (usize, (usize, usize)) {
|
fn get_data_bounds(data: &[Vec<(usize, usize)>]) -> (usize, (usize, usize)) {
|
||||||
data.iter()
|
data.iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
|
@ -41,29 +42,18 @@ fn fill_grid_walls(data: &[Vec<(usize, usize)>], grid: &mut Matrix<Tile>) {
|
||||||
let mut path_iter = path.iter();
|
let mut path_iter = path.iter();
|
||||||
path_iter.next()
|
path_iter.next()
|
||||||
.map(|&start| path_iter
|
.map(|&start| path_iter
|
||||||
.fold(start, |(prev_r, prev_c), &(next_r, next_c)| {
|
.fold(start, |prev, &next| {
|
||||||
let (min_r, max_r) = (prev_r.min(next_r), prev_r.max(next_r));
|
grid.draw_line(prev, next, Tile::Rock);
|
||||||
let (min_c, max_c) = (prev_c.min(next_c), prev_c.max(next_c));
|
next
|
||||||
match prev_r == next_r {
|
|
||||||
true => (min_c..=max_c).into_iter()
|
|
||||||
.for_each(|c| grid[(prev_r, c)] = Tile::Rock),
|
|
||||||
false => (min_r..=max_r).into_iter()
|
|
||||||
.for_each(|r| grid[(r, prev_c)] = Tile::Rock),
|
|
||||||
};
|
|
||||||
(next_r, next_c)
|
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn drop_sand(grid: &mut Matrix<Tile>, (row, col): (usize, usize)) -> Option<(usize, usize)> {
|
fn drop_sand(grid: &mut Matrix<Tile>, (row, col): (usize, usize)) -> Option<(usize, usize)> {
|
||||||
if grid[(row, col)] != Tile::Empty {
|
if grid[(row, col)] != Tile::Empty { return None; }
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ((_, min_c), (max_r, max_c)) = grid.bounds();
|
let ((_, min_c), (max_r, max_c)) = grid.get_bounds();
|
||||||
for r in row..max_r {
|
for r in row..max_r {
|
||||||
if grid[(r, col)] != Tile::Empty {
|
if grid[(r, col)] != Tile::Empty {
|
||||||
return if col == min_c {
|
return if col == min_c {
|
||||||
|
@ -84,7 +74,6 @@ fn drop_sand(grid: &mut Matrix<Tile>, (row, col): (usize, usize)) -> Option<(usi
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn solve1(data: &[Vec<(usize, usize)>]) -> i32 {
|
fn solve1(data: &[Vec<(usize, usize)>]) -> i32 {
|
||||||
let (min_c, max) = get_data_bounds(data);
|
let (min_c, max) = get_data_bounds(data);
|
||||||
let mut grid = Matrix::with_bounds((0, min_c), max, Tile::Empty);
|
let mut grid = Matrix::with_bounds((0, min_c), max, Tile::Empty);
|
||||||
|
@ -94,7 +83,6 @@ fn solve1(data: &[Vec<(usize, usize)>]) -> i32 {
|
||||||
while let Some(_) = drop_sand(&mut grid, (0, 500)) {
|
while let Some(_) = drop_sand(&mut grid, (0, 500)) {
|
||||||
sand_count += 1;
|
sand_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sand_count
|
sand_count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +102,6 @@ fn solve2(data: &[Vec<(usize, usize)>]) -> i32 {
|
||||||
while let Some(_) = drop_sand(&mut grid, (0, 500)) {
|
while let Some(_) = drop_sand(&mut grid, (0, 500)) {
|
||||||
sand_count += 1;
|
sand_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sand_count
|
sand_count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,19 +29,29 @@ impl<T: Clone> Matrix<T> {
|
||||||
let (offset_r, offset_c) = (min_r, min_c);
|
let (offset_r, offset_c) = (min_r, min_c);
|
||||||
Self { rows, cols, array: vec![value.clone(); rows * cols], offset_r, offset_c }
|
Self { rows, cols, array: vec![value.clone(); rows * cols], offset_r, offset_c }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_line(&mut self, (r1, c1): (usize, usize), (r2, c2): (usize, usize), value: T) {
|
||||||
|
let (min_r, max_r) = (r1.min(r2), r1.max(r2));
|
||||||
|
let (min_c, max_c) = (c1.min(c2), c1.max(c2));
|
||||||
|
match (r1 == r2, c1 == c2) {
|
||||||
|
(true, true) => self[(r1, c1)] = value.clone(),
|
||||||
|
(true, _) => (min_c..=max_c).into_iter()
|
||||||
|
.for_each(|c| self[(r1, c)] = value.clone()),
|
||||||
|
(_, true) => (min_r..=max_r).into_iter()
|
||||||
|
.for_each(|r| self[(r, c1)] = value.clone()),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Matrix<T> {
|
impl<T> Matrix<T> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn shape(&self) -> (usize, usize) {
|
pub fn get_shape(&self) -> (usize, usize) {
|
||||||
(self.rows, self.cols)
|
(self.rows, self.cols)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bounds(&self) -> ((usize, usize), (usize, usize)) {
|
pub fn get_bounds(&self) -> ((usize, usize), (usize, usize)) {
|
||||||
(
|
((self.offset_r, self.offset_c), (self.offset_r + self.rows, self.offset_c + self.cols))
|
||||||
(self.offset_r, self.offset_c),
|
|
||||||
(self.offset_r + self.rows, self.offset_c + self.cols)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reshape(mut self, (rows, cols): (usize, usize)) -> Self {
|
pub fn reshape(mut self, (rows, cols): (usize, usize)) -> Self {
|
||||||
|
|
Loading…
Reference in a new issue