diff --git a/day08/src/main.rs b/day08/src/main.rs index ace3d2322832f09c808ab8f4c27e35ee76f20a0c..ab8faec76de62c94272f88599406c71b97bf1546 100644 --- a/day08/src/main.rs +++ b/day08/src/main.rs @@ -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}"); } diff --git a/day08/src/matrix.rs b/day08/src/matrix.rs deleted file mode 100644 index aead067cfbf6d7a3f6c9f95d8a45b59a2324378a..0000000000000000000000000000000000000000 --- a/day08/src/matrix.rs +++ /dev/null @@ -1,208 +0,0 @@ -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 - } - } -} - -#[derive(Clone, Copy)] -pub struct MatrixCollumns<'a, T: Clone> { - parent: &'a Matrix<T>, - index: usize, -} - -impl<'a, T: Clone> MatrixCollumns<'a, T> { - pub fn new(parent: &'a Matrix<T>) -> Self { - Self { parent, index: 0 } - } -} - -impl<'a, T: Clone> Iterator for MatrixCollumns<'a, T> { - type Item = MatrixCollumn<'a, T>; - - fn next(&mut self) -> Option<Self::Item> { - if self.index < self.parent.width { - self.index += 1; - Some(MatrixCollumn::new(self.clone(), self.index - 1)) - } else { - None - } - } -} - -pub struct MatrixCollumn<'a, T: Clone> { - parent: MatrixCollumns<'a, T>, - offset: usize, - index: usize, -} - -impl<'a, T: Clone> MatrixCollumn<'a, T> { - pub fn new(parent: MatrixCollumns<'a, T>, offset: usize) -> Self { - Self { - parent, - offset, - index: 0, - } - } -} - -impl<'a, T: Clone> Iterator for MatrixCollumn<'a, T> { - type Item = &'a T; - - fn next(&mut self) -> Option<Self::Item> { - if self.index < self.parent.parent.height { - self.index += 1; - Some( - &self.parent.parent.elements - [self.offset + (self.index - 1) * self.parent.parent.width], - ) - } else { - None - } - } -} - -impl<'a, T: Clone> ExactSizeIterator for MatrixCollumn<'a, T> {} - -pub struct MatrixLines<'a, T>(Chunks<'a, T>); - -impl<'a, T> Iterator for MatrixLines<'a, T> { - type Item = &'a [T]; - - fn next(&mut self) -> Option<Self::Item> { - self.0.next() - } -} - -impl<'a, T> ExactSizeIterator for MatrixLines<'a, T> {} - -pub struct MatrixLinesMut<'a, T>(ChunksMut<'a, T>); - -impl<'a, T> Iterator for MatrixLinesMut<'a, T> { - type Item = &'a mut [T]; - - fn next(&mut self) -> Option<Self::Item> { - self.0.next() - } -} - -impl<'a, T> ExactSizeIterator for MatrixLinesMut<'a, T> {} diff --git a/day08/src/matrix/collumns.rs b/day08/src/matrix/collumns.rs new file mode 100644 index 0000000000000000000000000000000000000000..925eca629b17f85528d5717448e0ac3895368795 --- /dev/null +++ b/day08/src/matrix/collumns.rs @@ -0,0 +1,164 @@ +use std::marker::PhantomData; + +#[derive(Clone, Copy)] +pub struct MatrixCollumns<'a, T: Clone> { + parent: &'a super::Matrix<T>, + index: usize, +} + +impl<'a, T: Clone> MatrixCollumns<'a, T> { + pub fn new(parent: &'a super::Matrix<T>) -> Self { + Self { parent, index: 0 } + } +} + +impl<'a, T: Clone> Iterator for MatrixCollumns<'a, T> { + type Item = MatrixCollumn<'a, T>; + + fn next(&mut self) -> Option<Self::Item> { + if self.index < self.parent.width { + self.index += 1; + Some(MatrixCollumn::new(self.clone(), self.index - 1)) + } else { + None + } + } +} + +pub struct MatrixCollumn<'a, T: Clone> { + parent: MatrixCollumns<'a, T>, + offset: usize, + index: usize, +} + +impl<'a, T: Clone> MatrixCollumn<'a, T> { + pub fn new(parent: MatrixCollumns<'a, T>, offset: usize) -> Self { + Self { + parent, + offset, + index: 0, + } + } +} + +impl<'a, T: Clone> Iterator for MatrixCollumn<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option<Self::Item> { + if self.index < self.parent.parent.height { + self.index += 1; + Some( + &self.parent.parent.elements + [self.offset + (self.index - 1) * self.parent.parent.width], + ) + } else { + None + } + } +} + +impl<'a, T: Clone> ExactSizeIterator for MatrixCollumn<'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: Clone> Iterator for MatrixCollumnsMut<'a, T> { + type Item = MatrixCollumnMut<'a, T>; + + fn next(&mut self) -> Option<Self::Item> { + 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)) + } +} + +pub struct MatrixCollumnMut<'a, T: Clone> { + collumn: usize, + index: usize, + back_index: Option<usize>, + obj: *mut super::Matrix<T>, + phantom: PhantomData<&'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: 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; + 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 + } + } + + 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 + } + } +} diff --git a/day08/src/matrix/lines.rs b/day08/src/matrix/lines.rs new file mode 100644 index 0000000000000000000000000000000000000000..cc5d575973ac7c7228dbe5c4c329b16595d7e747 --- /dev/null +++ b/day08/src/matrix/lines.rs @@ -0,0 +1,53 @@ +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 diff --git a/day08/src/matrix/mod.rs b/day08/src/matrix/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..13e2ab4f1dbff6dc746f9d36f5611635458d98e3 --- /dev/null +++ b/day08/src/matrix/mod.rs @@ -0,0 +1,64 @@ +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) + } +}