Skip to content
Snippets Groups Projects
Commit 2fd18032 authored by Evy Storozhenko's avatar Evy Storozhenko
Browse files

finish matrix iterators

parent ee39b08e
Branches 08-collumns
No related tags found
No related merge requests found
......@@ -5,6 +5,7 @@ mod matrix;
use matrix::Matrix;
use std::fs::read_to_string;
#[allow(unused)]
fn solve_without_types() {
let data = read_to_string("data.txt").unwrap();
let width = data.lines().next().unwrap().len();
......@@ -89,7 +90,7 @@ fn main() {
let mut datamat = Matrix::new_from_str(&data, |c| (c.to_digit(10).unwrap(), false));
datamat.lines_mut().for_each(|line| {
line.iter_mut().fold(-1, |acc, v| {
line.fold(-1, |acc, v| {
if v.0 as i32 > acc {
v.1 = true;
v.0 as i32
......@@ -99,7 +100,7 @@ fn main() {
});
});
datamat.lines_mut().for_each(|line| {
line.iter_mut().rev().fold(-1, |acc, v| {
line.rev().fold(-1, |acc, v| {
if v.0 as i32 > acc {
v.1 = true;
v.0 as i32
......@@ -120,8 +121,22 @@ fn main() {
});
});
datamat.collumns_mut().for_each(|col| {
col.rev().fold(-1, |acc, v| {
if v.0 as i32 > acc {
v.1 = true;
v.0 as i32
} else {
acc
}
});
});
datamat.lines().for_each(|v| {
v.iter().for_each(|x| print!("{}", if x.1 { 'A' } else { '_' }));
v.for_each(|x| print!("{}", if x.1 { 'A' } else { '_' }));
println!();
})
});
let visible = datamat.elements.iter().filter(|v| v.1).count();
println!("Visible trees: {visible}");
}
use std::{
iter::{repeat_with, Take},
marker::PhantomData,
slice::{Chunks, ChunksMut},
};
pub struct Matrix<T: Clone> {
pub width: usize,
pub height: usize,
pub elements: Vec<T>,
}
impl<T: Clone> Matrix<T> {
pub fn new() -> Self {
Self {
width: 0,
height: 0,
elements: Vec::new(),
}
}
pub fn new_from_str<F>(source: &str, f: F) -> Self
where
F: FnMut(char) -> T,
{
let mut f_mut = f;
let mut iter = source.chars().filter(|c| c != &'\n');
let width = source.lines().next().unwrap_or("").len();
let height = source.lines().count();
Self {
width,
height,
elements: repeat_with(|| f_mut(iter.next().unwrap()))
.take(width * height)
.collect::<Vec<_>>(),
}
}
pub fn lines(&self) -> MatrixLines<T> {
MatrixLines(self.elements.chunks(self.width))
}
pub fn lines_mut(&mut self) -> MatrixLinesMut<T> {
MatrixLinesMut(self.elements.chunks_mut(self.width))
}
pub fn collumns_mut(&mut self) -> impl Iterator<Item = MatrixCollumnMut<'_, T>> {
let mut collumn = 0;
let width = self.width;
MatrixCollumnsMut {
iter: repeat_with(move || {
let i = collumn;
collumn += 1;
MatrixCollumnMut {
collumn: i,
width,
index: 0,
obj: self,
phantom: PhantomData,
}
})
.take(width),
}
}
pub fn collumns(&self) -> MatrixCollumns<T> {
MatrixCollumns::new(self)
}
pub fn resize(&mut self, width: usize, height: usize, value: T)
where
T: Clone,
{
self.width = width;
self.height = height;
self.elements.resize(width * height, value);
}
}
pub struct MatrixCollumnsMut<'a, T, I>
where
T: Clone + 'a,
I: Iterator<Item = MatrixCollumnMut<'a, T>>,
{
iter: Take<I>,
}
impl<'a, T, I> Iterator for MatrixCollumnsMut<'a, T, I>
where
T: Clone + 'a,
I: Iterator<Item = MatrixCollumnMut<'a, T>>,
{
type Item = MatrixCollumnMut<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}
pub struct MatrixCollumnMut<'a, T: Clone> {
width: usize,
collumn: usize,
index: usize,
obj: *mut Matrix<T>,
phantom: PhantomData<&'a T>,
}
impl<'a, T: Clone> Iterator for MatrixCollumnMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let i = self.index;
self.index += 1;
if i < self.width {
Some(unsafe {
&mut *(*self.obj)
.elements
.as_mut_ptr()
.add(self.collumn + i * self.width)
})
} else {
None
}
}
}
use std::marker::PhantomData;
#[derive(Clone, Copy)]
pub struct MatrixCollumns<'a, T: Clone> {
parent: &'a Matrix<T>,
parent: &'a super::Matrix<T>,
index: usize,
}
impl<'a, T: Clone> MatrixCollumns<'a, T> {
pub fn new(parent: &'a Matrix<T>) -> Self {
pub fn new(parent: &'a super::Matrix<T>) -> Self {
Self { parent, index: 0 }
}
}
......@@ -183,26 +59,106 @@ impl<'a, T: Clone> Iterator for MatrixCollumn<'a, T> {
impl<'a, T: Clone> ExactSizeIterator for MatrixCollumn<'a, T> {}
pub struct MatrixLines<'a, T>(Chunks<'a, T>);
pub struct MatrixCollumnsMut<'a, T: Clone> {
obj: *mut super::Matrix<T>,
collumn: usize,
phantom: PhantomData<&'a T>,
}
impl<'a, T: Clone> MatrixCollumnsMut<'a, T> {
pub fn new(parent: &'a mut super::Matrix<T>) -> Self {
Self {
obj: parent,
collumn: 0,
phantom: PhantomData,
}
}
}
impl<'a, T> Iterator for MatrixLines<'a, T> {
type Item = &'a [T];
impl<'a, T: Clone> Iterator for MatrixCollumnsMut<'a, T> {
type Item = MatrixCollumnMut<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
let i = self.collumn;
let width = unsafe { (*self.obj).width };
let height = unsafe { (*self.obj).width };
if i >= width {
return None;
}
self.collumn += 1;
Some(MatrixCollumnMut::new(self.obj, i, height))
}
}
impl<'a, T> ExactSizeIterator for MatrixLines<'a, T> {}
pub struct MatrixCollumnMut<'a, T: Clone> {
collumn: usize,
index: usize,
back_index: Option<usize>,
obj: *mut super::Matrix<T>,
phantom: PhantomData<&'a T>,
}
pub struct MatrixLinesMut<'a, T>(ChunksMut<'a, T>);
impl<'a, T: Clone> MatrixCollumnMut<'a, T> {
pub fn new(obj: *mut super::Matrix<T>, collumn: usize, height: usize) -> Self {
Self {
collumn,
index: 0,
back_index: Some(height - 1),
obj,
phantom: PhantomData,
}
}
}
impl<'a, T> Iterator for MatrixLinesMut<'a, T> {
type Item = &'a mut [T];
impl<'a, T: Clone> Iterator for MatrixCollumnMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
let i = self.index;
self.index += 1;
let width = unsafe { (*self.obj).width };
let height = unsafe { (*self.obj).height };
if i < height && self.back_index.is_some() && i != (self.back_index.clone().unwrap() + 1) {
Some(unsafe {
&mut *(*self.obj)
.elements
.as_mut_ptr()
.add(self.collumn + i * width)
})
} else {
None
}
}
impl<'a, T> ExactSizeIterator for MatrixLinesMut<'a, T> {}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = (unsafe { (*self.obj).height } - self.index) as usize;
(remaining, Some(remaining))
}
}
impl<'a, T: Clone> ExactSizeIterator for MatrixCollumnMut<'a, T> {}
impl<'a, T: Clone> DoubleEndedIterator for MatrixCollumnMut<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.back_index.is_none() {
return None;
}
let i = self.back_index.clone().unwrap();
self.back_index = if i > 0 { Some(i - 1) } else { None };
let width = unsafe { (*self.obj).width };
let height = unsafe { (*self.obj).height };
if i < height && (i + 1) != self.index {
Some(unsafe {
&mut *(*self.obj)
.elements
.as_mut_ptr()
.add(self.collumn + i * width)
})
} else {
None
}
}
}
use std::slice::{Chunks, ChunksMut};
use super::Matrix;
pub struct MatrixLines<'a, T>(Chunks<'a, T>);
impl<'a, T: Clone> MatrixLines<'a, T> {
pub fn new(parent: &'a Matrix<T>) -> Self {
Self(parent.elements.chunks(parent.width))
}
}
impl<'a, T> Iterator for MatrixLines<'a, T> {
type Item = core::slice::Iter<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
match self.0.next() {
Some(v) => Some(v.iter()),
None => None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl<'a, T> ExactSizeIterator for MatrixLines<'a, T> {}
pub struct MatrixLinesMut<'a, T>(ChunksMut<'a, T>);
impl<'a, T: Clone> MatrixLinesMut<'a, T> {
pub fn new(parent: &'a mut Matrix<T>) -> Self {
Self(parent.elements.chunks_mut(parent.width))
}
}
impl<'a, T> Iterator for MatrixLinesMut<'a, T> {
type Item = core::slice::IterMut<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
match self.0.next() {
Some(v) => Some(v.iter_mut()),
None => None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl<'a, T> ExactSizeIterator for MatrixLinesMut<'a, T> {}
\ No newline at end of file
use std::iter::repeat_with;
use self::{
collumns::{MatrixCollumns, MatrixCollumnsMut},
lines::{MatrixLines, MatrixLinesMut},
};
mod collumns;
mod lines;
pub struct Matrix<T: Clone> {
pub width: usize,
pub height: usize,
pub elements: Vec<T>,
}
impl<T: Clone> Matrix<T> {
#[allow(unused)]
pub fn new() -> Self {
Self {
width: 0,
height: 0,
elements: Vec::new(),
}
}
#[allow(unused)]
pub fn new_from_str<F>(source: &str, f: F) -> Self
where
F: FnMut(char) -> T,
{
let mut f_mut = f;
let mut iter = source.chars().filter(|c| c != &'\n');
let width = source.lines().next().unwrap_or("").len();
let height = source.lines().count();
Self {
width,
height,
elements: repeat_with(|| f_mut(iter.next().unwrap()))
.take(width * height)
.collect::<Vec<_>>(),
}
}
#[allow(unused)]
pub fn lines(&self) -> MatrixLines<T> {
MatrixLines::new(self)
}
#[allow(unused)]
pub fn lines_mut(&mut self) -> MatrixLinesMut<T> {
MatrixLinesMut::new(self)
}
#[allow(unused)]
pub fn collumns(&self) -> MatrixCollumns<T> {
MatrixCollumns::new(self)
}
#[allow(unused)]
pub fn collumns_mut(&mut self) -> MatrixCollumnsMut<T> {
MatrixCollumnsMut::new(self)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment