diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..46e1d1b833aa1e9d18bea1a682a22f8597f6dfd3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# Advent of Code 2022
+*Quality may vary*
\ No newline at end of file
diff --git a/day08/src/main.rs b/day08/src/main.rs
index b44db1403ce76cf281655f88b9181e6805ae1211..11cbf196a87ce95cd8050d3953541f92326e672f 100644
--- a/day08/src/main.rs
+++ b/day08/src/main.rs
@@ -1,11 +1,14 @@
+mod matrix;
+
+use matrix::Matrix;
 use std::fs::read_to_string;
 
-fn main() {
+fn solve_without_types() {
     let data = read_to_string("data.txt").unwrap();
-
-    let mut vismap = Vec::<Vec<bool>>::new();
     let width = data.lines().next().unwrap().len();
     let height = data.lines().count();
+
+    let mut vismap = Vec::<Vec<bool>>::new();
     vismap.resize(height, {
         let mut vec = Vec::new();
         vec.resize(width, false);
@@ -72,8 +75,45 @@ fn main() {
             .for_each(|c| print!("{}", if *c { 'A' } else { '_' }));
         println!();
     });
-    let trees = vismap.iter().map(|v| {
-        v.iter().filter(|&&v| v).count()
-    }).sum::<usize>();
+    let trees = vismap
+        .iter()
+        .map(|v| v.iter().filter(|&&v| v).count())
+        .sum::<usize>();
     println!("Trees: {trees}");
 }
+
+fn main() {
+    let data = read_to_string("data.txt").unwrap();
+    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| {
+            if v.0 as i32 > acc {
+                v.1 = true;
+                v.0 as i32
+            } else {
+                acc
+            }
+        });
+    });
+    datamat.lines_mut().for_each(|line| {
+        line.iter_mut().rev().fold(-1, |acc, v| {
+            if v.0 as i32 > acc {
+                v.1 = true;
+                v.0 as i32
+            } else {
+                acc
+            }
+        });
+    });
+
+    datamat.collumns().for_each(|col| {
+        col.for_each(|v| print!("{}", v.0));
+        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
new file mode 100644
index 0000000000000000000000000000000000000000..ad22455c95ed96f0e5af42f48e8f5165dce2d352
--- /dev/null
+++ b/day08/src/matrix.rs
@@ -0,0 +1,139 @@
+use std::{
+    iter::repeat_with,
+    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(&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);
+    }
+}
+
+#[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
+        }
+    }
+}
+
+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> {}