From 93bc79289463e28f588743aaebb34aa1bff61b30 Mon Sep 17 00:00:00 2001 From: Maciej Jur Date: Sat, 10 Dec 2022 16:30:16 +0100 Subject: [PATCH] 2022 rust matrix --- 2022/rust/src/solutions/day08.rs | 77 +++++++++++++++----------------- 2022/rust/src/utils/matrix.rs | 21 ++++++--- 2 files changed, 52 insertions(+), 46 deletions(-) diff --git a/2022/rust/src/solutions/day08.rs b/2022/rust/src/solutions/day08.rs index 0aa286c..8a5d9b7 100644 --- a/2022/rust/src/solutions/day08.rs +++ b/2022/rust/src/solutions/day08.rs @@ -17,11 +17,11 @@ fn mark_visible( data: &Matrix, visible: &mut Matrix, last_height: &mut i32, - (row, col): (usize, usize) + index: (usize, usize) ) { - let height = *data.get_at(row, col); + let height = data[index]; if height > *last_height { - visible.set_at(row, col, true); + visible[index] = true; *last_height = height; } } @@ -59,45 +59,43 @@ fn solve1(data: &Matrix) -> usize { } fn find_scores(data: &Matrix) -> Matrix { + let mut scores = Matrix::with_shape(data.shape(), 1); + let (rows, cols) = data.shape(); - let mut scores = Matrix::with_shape((rows, cols), 1); + for (row, col) in data.cell_indices() { + let mut score = 1; + let current = data[(row, col)]; - for row in 0..rows { - for col in 0..cols { - let mut score = 1; - let current = *data.get_at(row, col); + let mut temp = 0; + for c in (0..col).rev() { + temp += 1; + if data[(row, c)] >= current { break }; + } + score *= temp; - let mut temp = 0; - for c in (0..col).rev() { - temp += 1; - if *data.get_at(row, c) >= current { break }; - } - score *= temp; + let mut temp = 0; + for c in (col+1)..cols { + temp += 1; + if data[(row, c)] >= current { break }; + } + score *= temp; - let mut temp = 0; - for c in (col+1)..cols { - temp += 1; - if *data.get_at(row, c) >= current { break }; - } - score *= temp; + let mut temp = 0; + for r in (0..row).rev() { + temp += 1; + if data[(r, col)] >= current { break }; + } + score *= temp; - let mut temp = 0; - for r in (0..row).rev() { - temp += 1; - if *data.get_at(r, col) >= current { break }; - } - score *= temp; + let mut temp = 0; + for r in (row+1)..rows { + temp += 1; + if data[(r, col)] >= current { break }; + } + score *= temp; - let mut temp = 0; - for r in (row+1)..rows { - temp += 1; - if *data.get_at(r, col) >= current { break }; - } - score *= temp; - - scores.set_at(row, col, score); - }; - }; + scores[(row, col)] = score; + } scores } @@ -129,16 +127,15 @@ mod tests { #[test] fn part1() { - let data = parse_data(DATA); - assert_eq!(21, solve1(&data)); + assert_eq!(21, solve1(&parse_data(DATA))); } #[test] fn part2() { let data = parse_data(DATA); let scores = find_scores(&data); - assert_eq!(4, *scores.get_at(1, 2)); - assert_eq!(8, *scores.get_at(3, 2)); + assert_eq!(4, scores[(1, 2)]); + assert_eq!(8, scores[(3, 2)]); assert_eq!(8, solve2(&data)); } } diff --git a/2022/rust/src/utils/matrix.rs b/2022/rust/src/utils/matrix.rs index f6a4e37..0271fa0 100644 --- a/2022/rust/src/utils/matrix.rs +++ b/2022/rust/src/utils/matrix.rs @@ -20,6 +20,7 @@ impl Matrix { } impl Matrix { + #[inline(always)] pub fn shape(&self) -> (usize, usize) { (self.rows, self.cols) } @@ -30,12 +31,12 @@ impl Matrix { self } - pub fn reshape_rows(mut self, rows: usize) -> Self { + pub fn reshape_rows(self, rows: usize) -> Self { let cols = self.cols / rows; self.reshape((rows, cols)) } - pub fn reshape_cols(mut self, cols: usize) -> Self { + pub fn reshape_cols(self, cols: usize) -> Self { let rows = self.rows / cols; self.reshape((rows, cols)) } @@ -63,21 +64,29 @@ impl Matrix { self.array[offset] = value; } + pub fn cell_indices(&self) -> impl Iterator + '_ { + (0..self.rows).into_iter() + .flat_map(|row| (0..self.cols).into_iter().map(move |col| (row, col))) + } + + #[inline(always)] fn get_offset(&self, row: usize, col: usize) -> usize { row * self.cols + col } } -impl Index for Matrix { +impl Index<(usize, usize)> for Matrix { type Output = T; - fn index(&self, index: usize) -> &Self::Output { + fn index(&self, (row, col): (usize, usize)) -> &Self::Output { + let index = self.get_offset(row, col); &self.array[index] } } -impl IndexMut for Matrix { - fn index_mut(&mut self, index: usize) -> &mut Self::Output { +impl IndexMut<(usize, usize)> for Matrix { + fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut Self::Output { + let index = self.get_offset(row, col); &mut self.array[index] } }