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

finish matrix iterators

parent ee39b08e
No related branches found
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