From ee39b08e55bf8e5884afe44c746ad1c2fe425498 Mon Sep 17 00:00:00 2001
From: Evy Garden <evysgarden@protonmail.com>
Date: Wed, 14 Dec 2022 16:21:55 +0100
Subject: [PATCH] added mutable collumns

---
 day08/src/main.rs   | 22 +++++++++-----
 day08/src/matrix.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 85 insertions(+), 8 deletions(-)

diff --git a/day08/src/main.rs b/day08/src/main.rs
index 11cbf19..ace3d23 100644
--- a/day08/src/main.rs
+++ b/day08/src/main.rs
@@ -1,3 +1,5 @@
+#![feature(type_alias_impl_trait)]
+
 mod matrix;
 
 use matrix::Matrix;
@@ -107,13 +109,19 @@ fn main() {
         });
     });
 
-    datamat.collumns().for_each(|col| {
-        col.for_each(|v| print!("{}", v.0));
+    datamat.collumns_mut().for_each(|col| {
+        col.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 { '_' }));
         println!();
     })
-
-    // datamat.lines().for_each(|v| {
-    //     v.iter().for_each(|x| print!("{}", if x.1 { 'A' } else { '_' }));
-    //     println!();
-    // })
 }
diff --git a/day08/src/matrix.rs b/day08/src/matrix.rs
index ad22455..aead067 100644
--- a/day08/src/matrix.rs
+++ b/day08/src/matrix.rs
@@ -1,5 +1,6 @@
 use std::{
-    iter::repeat_with,
+    iter::{repeat_with, Take},
+    marker::PhantomData,
     slice::{Chunks, ChunksMut},
 };
 
@@ -43,6 +44,25 @@ impl<T: Clone> Matrix<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)
     }
@@ -57,6 +77,53 @@ impl<T: Clone> Matrix<T> {
     }
 }
 
+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>,
@@ -114,6 +181,8 @@ 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>);
 
 impl<'a, T> Iterator for MatrixLines<'a, T> {
-- 
GitLab