diff --git a/day06/.gitignore b/day06/.gitignore
new file mode 100644
index 0000000..907dcd8
--- /dev/null
+++ b/day06/.gitignore
@@ -0,0 +1,2 @@
+target
+debug
diff --git a/day06/Cargo.lock b/day06/Cargo.lock
new file mode 100644
index 0000000..5148a23
--- /dev/null
+++ b/day06/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "day06"
+version = "0.1.0"
diff --git a/day06/Cargo.toml b/day06/Cargo.toml
new file mode 100644
index 0000000..6bd04ba
--- /dev/null
+++ b/day06/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "day06"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/day06/src/main.rs b/day06/src/main.rs
new file mode 100644
index 0000000..8da645f
--- /dev/null
+++ b/day06/src/main.rs
@@ -0,0 +1,130 @@
+use std::fs;
+
+#[derive(Debug, Clone, Copy)]
+enum Dir {
+ Up,
+ Down,
+ Left,
+ Right,
+}
+
+impl From
for i32 {
+ fn from(value: Dir) -> Self {
+ match value {
+ Dir::Up => 1,
+ Dir::Down => 2,
+ Dir::Left => 3,
+ Dir::Right => 4,
+ }
+ }
+}
+
+impl Dir {
+ fn move_point(&self, point: (usize, usize), max: (usize, usize)) -> Option<(usize, usize)> {
+ match self {
+ Dir::Up if point.1 > 0 => Some((point.0, point.1 - 1)),
+ Dir::Down if point.1 < max.1 => Some((point.0, point.1 + 1)),
+ Dir::Left if point.0 > 0 => Some((point.0 - 1, point.1)),
+ Dir::Right if point.0 < max.0 => Some((point.0 + 1, point.1)),
+ _ => None,
+ }
+ }
+
+ fn rotate(&self) -> Dir {
+ match self {
+ Dir::Up => Dir::Right,
+ Dir::Down => Dir::Left,
+ Dir::Left => Dir::Up,
+ Dir::Right => Dir::Down,
+ }
+ }
+}
+
+fn main() {
+ let input = fs::read_to_string("input.txt").unwrap();
+
+ let mut pos = (0, 0);
+ let mut dir = Dir::Up;
+ let mut no_edit_grid = input
+ .lines()
+ .filter(|&l| !l.is_empty())
+ .enumerate()
+ .map(|(y, l)| {
+ l.chars()
+ .enumerate()
+ .map(|(x, c)| match c {
+ '#' => -1,
+ '.' => 0,
+ '^' => {
+ pos = (x, y);
+ 0
+ }
+ _ => panic!("invalid char"),
+ })
+ .collect::>()
+ })
+ .collect::>>();
+ let original_grid = no_edit_grid.clone();
+ let oirignal_pos = pos;
+ let original_dir = dir;
+
+ loop {
+ no_edit_grid[pos.1][pos.0] = dir.into();
+ let next_pos =
+ match dir.move_point(pos, (no_edit_grid[0].len() - 1, no_edit_grid.len() - 1)) {
+ Some(p) => p,
+ None => break,
+ };
+
+ match no_edit_grid[next_pos.1][next_pos.0] {
+ -1 => dir = dir.rotate(),
+ _ => pos = next_pos,
+ }
+ }
+
+ println!(
+ "Part 1: {}",
+ no_edit_grid
+ .iter()
+ .map(|l| l.iter().filter(|&x| *x > 0).count())
+ .sum::()
+ );
+
+ let mut loops = -1;
+ for (x, y) in no_edit_grid
+ .iter()
+ .map(|l| {
+ l.iter().enumerate().filter_map(|(x, c)| match *c > 0 {
+ true => Some(x),
+ false => None,
+ })
+ })
+ .enumerate()
+ .flat_map(|(y, l)| l.map(move |x| (x, y)))
+ {
+ let mut edited_grid = original_grid.clone();
+ let mut pos = oirignal_pos;
+ let mut dir = original_dir;
+ edited_grid[y][x] = -1;
+
+ loop {
+ if (edited_grid[pos.1][pos.0] & (2 << i32::from(dir))) != 0 {
+ loops += 1;
+ break;
+ }
+ edited_grid[pos.1][pos.0] |= 2 << i32::from(dir);
+ let next_pos =
+ match dir.move_point(pos, (no_edit_grid[0].len() - 1, no_edit_grid.len() - 1)) {
+ Some(p) => p,
+ None => break,
+ };
+
+ match edited_grid[next_pos.1][next_pos.0] {
+ -1 => dir = dir.rotate(),
+ _ => pos = next_pos,
+ }
+ }
+ }
+
+ println!("Part 2: {}", loops);
+}