2022 rust matrix
This commit is contained in:
parent
5d380ec65d
commit
8696246977
|
@ -1,6 +1,6 @@
|
|||
#![allow(dead_code)]
|
||||
use std::cmp::max;
|
||||
use crate::utils;
|
||||
use crate::utils::matrix::Matrix;
|
||||
|
||||
|
||||
pub fn run() -> () {
|
||||
|
@ -14,45 +14,39 @@ pub fn run() -> () {
|
|||
|
||||
#[inline(always)]
|
||||
fn mark_visible(
|
||||
data: &[Vec<i32>],
|
||||
visible: &mut Vec<Vec<bool>>,
|
||||
data: &Matrix<i32>,
|
||||
visible: &mut Matrix<bool>,
|
||||
last_height: &mut i32,
|
||||
row: usize,
|
||||
col: usize
|
||||
(row, col): (usize, usize)
|
||||
) {
|
||||
let height = data[row][col];
|
||||
let height = *data.get_at(row, col);
|
||||
if height > *last_height {
|
||||
visible[row][col] = true;
|
||||
visible.set_at(row, col, true);
|
||||
*last_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
fn create_mask(data: &[Vec<i32>]) -> Vec<Vec<bool>> {
|
||||
let rows = data.len();
|
||||
let cols = data[0].len();
|
||||
|
||||
let mut visible: Vec<Vec<bool>> = (0..rows)
|
||||
.into_iter()
|
||||
.map(|_| (0..cols).into_iter().map(|_| false).collect())
|
||||
.collect();
|
||||
fn create_mask(data: &Matrix<i32>) -> Matrix<bool> {
|
||||
let (rows, cols) = data.shape();
|
||||
let mut visible = Matrix::with_shape((rows, cols), false);
|
||||
|
||||
for row in 0..rows {
|
||||
let mut last_height = i32::MIN;
|
||||
for col in 0..cols {
|
||||
mark_visible(data, &mut visible, &mut last_height, row, col);
|
||||
mark_visible(data, &mut visible, &mut last_height, (row, col));
|
||||
}
|
||||
let mut last_height = i32::MIN;
|
||||
for col in (0..cols).rev() {
|
||||
mark_visible(data, &mut visible, &mut last_height, row, col);
|
||||
mark_visible(data, &mut visible, &mut last_height, (row, col));
|
||||
}
|
||||
// Transposed passes
|
||||
let mut last_height = i32::MIN;
|
||||
for col in 0..cols {
|
||||
mark_visible(data, &mut visible, &mut last_height, col, row);
|
||||
mark_visible(data, &mut visible, &mut last_height, (col, row));
|
||||
}
|
||||
let mut last_height = i32::MIN;
|
||||
for col in (0..cols).rev() {
|
||||
mark_visible(data, &mut visible, &mut last_height, col, row);
|
||||
mark_visible(data, &mut visible, &mut last_height, (col, row));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -60,78 +54,64 @@ fn create_mask(data: &[Vec<i32>]) -> Vec<Vec<bool>> {
|
|||
}
|
||||
|
||||
|
||||
fn solve1(data: &[Vec<i32>]) -> usize {
|
||||
create_mask(data).into_iter().map(|row| row.iter().filter(|&e| *e).count()).sum()
|
||||
fn solve1(data: &Matrix<i32>) -> usize {
|
||||
create_mask(data).iter().filter(|&e| *e).count()
|
||||
}
|
||||
|
||||
fn find_scores(data: &[Vec<i32>]) -> Vec<Vec<i32>> {
|
||||
let rows = data.len();
|
||||
let cols = data[0].len();
|
||||
|
||||
let mut scores: Vec<Vec<i32>> = (0..rows)
|
||||
.into_iter()
|
||||
.map(|_| (0..cols).into_iter().map(|_| 1).collect())
|
||||
.collect();
|
||||
fn find_scores(data: &Matrix<i32>) -> Matrix<i32> {
|
||||
let (rows, cols) = data.shape();
|
||||
let mut scores = Matrix::with_shape((rows, cols), 1);
|
||||
|
||||
for row in 0..rows {
|
||||
for col in 0..cols {
|
||||
let mut score = 1;
|
||||
let current = data[row][col];
|
||||
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 };
|
||||
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 };
|
||||
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 };
|
||||
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 };
|
||||
if *data.get_at(r, col) >= current { break };
|
||||
}
|
||||
score *= temp;
|
||||
|
||||
scores[row][col] = score;
|
||||
scores.set_at(row, col, score);
|
||||
};
|
||||
};
|
||||
|
||||
scores
|
||||
}
|
||||
|
||||
fn solve2(data: &[Vec<i32>]) -> i32 {
|
||||
let scores = find_scores(data);
|
||||
|
||||
let reducer = |a, b| max(a, b);
|
||||
scores.into_iter()
|
||||
.map(|row| row.iter().copied().reduce(reducer).unwrap())
|
||||
.reduce(reducer)
|
||||
.unwrap()
|
||||
fn solve2(data: &Matrix<i32>) -> i32 {
|
||||
find_scores(data).into_iter().reduce(i32::max).unwrap()
|
||||
}
|
||||
|
||||
|
||||
fn parse_data<T: AsRef<str>>(data: &[T]) -> Vec<Vec<i32>> {
|
||||
fn parse_data<T: AsRef<str>>(data: &[T]) -> Matrix<i32> {
|
||||
data.iter()
|
||||
.map(|line| line.as_ref()
|
||||
.chars()
|
||||
.map(|c| c.to_digit(10).unwrap() as i32)
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
.collect::<Vec<_>>()
|
||||
.flat_map(|line| line.as_ref().chars().map(|c| c.to_digit(10).unwrap() as i32))
|
||||
.collect::<Matrix<_>>()
|
||||
.reshape_rows(data.len())
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,8 +137,8 @@ mod tests {
|
|||
fn part2() {
|
||||
let data = parse_data(DATA);
|
||||
let scores = find_scores(&data);
|
||||
assert_eq!(4, scores[1][2]);
|
||||
assert_eq!(8, scores[3][2]);
|
||||
assert_eq!(4, *scores.get_at(1, 2));
|
||||
assert_eq!(8, *scores.get_at(3, 2));
|
||||
assert_eq!(8, solve2(&data));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(dead_code)]
|
||||
use std::ops::{Deref, Index, IndexMut};
|
||||
use std::slice::ChunksExact;
|
||||
use std::ops::{Index, IndexMut};
|
||||
use std::slice::{ChunksExact, Iter};
|
||||
|
||||
|
||||
pub struct Matrix<T> {
|
||||
|
@ -19,40 +19,33 @@ impl<T: Default + Clone> Matrix<T> {
|
|||
}
|
||||
}
|
||||
|
||||
// impl<'a, T: Copy + 'a> Matrix<T> {
|
||||
// pub fn build_from<N, O>(container: O) -> Self
|
||||
// where
|
||||
// N: IntoIterator<Item=&'a T> + 'a,
|
||||
// O: IntoIterator<Item=&'a N>,
|
||||
// {
|
||||
// let mut array: Vec<T> = Vec::new();
|
||||
// let mut cols = Vec::new();
|
||||
// for row in container {
|
||||
// let len = (&row).into_iter()
|
||||
// .fold(0, |cols, item| {
|
||||
// array.push(*item);
|
||||
// cols + 1
|
||||
// });
|
||||
// cols.push(len);
|
||||
// };
|
||||
// Self { array, rows: array.len() / cols[0], cols: cols[0] }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<T> Matrix<T> {
|
||||
pub fn shape(&self) -> (usize, usize) {
|
||||
(self.rows, self.cols)
|
||||
}
|
||||
|
||||
pub fn reshape(mut self, (rows, cols): (usize, usize)) -> Self {
|
||||
assert_eq!(self.rows * self.cols, rows * cols);
|
||||
(self.rows, self.cols) = (rows, cols);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn reshape_rows(mut self, rows: usize) -> Self {
|
||||
let cols = self.cols / rows;
|
||||
self.reshape((rows, cols))
|
||||
}
|
||||
|
||||
pub fn reshape_cols(mut self, cols: usize) -> Self {
|
||||
let rows = self.rows / cols;
|
||||
self.reshape((rows, cols))
|
||||
}
|
||||
|
||||
pub fn iter_rows(&self) -> ChunksExact<'_, T> {
|
||||
self.array.chunks_exact(self.cols)
|
||||
}
|
||||
|
||||
pub fn reshape(mut self, rows: usize, cols: usize) -> Matrix<T> {
|
||||
assert_eq!(self.rows * self.cols, rows * cols);
|
||||
self.rows = rows;
|
||||
self.cols = cols;
|
||||
self
|
||||
pub fn iter(&self) -> Iter<'_, T> {
|
||||
self.array.iter()
|
||||
}
|
||||
|
||||
pub fn get_at(&self, row: usize, col: usize) -> &T {
|
||||
|
@ -89,10 +82,38 @@ impl<T> IndexMut<usize> for Matrix<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for Matrix<T> {
|
||||
type Target = Vec<T>;
|
||||
pub struct MatrixIter<T> {
|
||||
matrix: Matrix<T>,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.array
|
||||
impl<T: Copy> IntoIterator for Matrix<T> {
|
||||
type Item = T;
|
||||
type IntoIter = MatrixIter<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
MatrixIter { matrix: self, index: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> Iterator for MatrixIter<T> {
|
||||
type Item = T;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.index < self.matrix.array.len() {
|
||||
true => {
|
||||
let current = self.index;
|
||||
self.index += 1;
|
||||
Some(self.matrix.array[current])
|
||||
}
|
||||
false => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromIterator<T> for Matrix<T> {
|
||||
fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self {
|
||||
let array = iter.into_iter().collect::<Vec<_>>();
|
||||
let cols = array.len();
|
||||
Matrix { array, cols, rows: 1 }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue