From fd47622c683810b6969e1c0925dfa3c2cc6c68d9 Mon Sep 17 00:00:00 2001 From: Samuel Ortion Date: Tue, 10 Dec 2024 13:28:03 +0100 Subject: [PATCH] day 6: part 1 & 2: rust --- 2024/days/06/part1/Cargo.toml | 6 ++ 2024/days/06/part1/src/main.rs | 106 ++++++++++++++++++++++++++++++ 2024/days/06/part2/Cargo.toml | 6 ++ 2024/days/06/part2/src/main.rs | 115 +++++++++++++++++++++++++++++++++ 4 files changed, 233 insertions(+) create mode 100644 2024/days/06/part1/Cargo.toml create mode 100644 2024/days/06/part1/src/main.rs create mode 100644 2024/days/06/part2/Cargo.toml create mode 100644 2024/days/06/part2/src/main.rs diff --git a/2024/days/06/part1/Cargo.toml b/2024/days/06/part1/Cargo.toml new file mode 100644 index 0000000..6bd04ba --- /dev/null +++ b/2024/days/06/part1/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day06" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/2024/days/06/part1/src/main.rs b/2024/days/06/part1/src/main.rs new file mode 100644 index 0000000..70261f9 --- /dev/null +++ b/2024/days/06/part1/src/main.rs @@ -0,0 +1,106 @@ + +struct Guardian { + x: usize, + y: usize, + dx: isize, + dy: isize, +} + +impl Guardian { + pub fn new(x: usize, y: usize) -> Self { + let dx = 0; + let dy = -1; + Guardian{ x, y, dx, dy } + } + + pub fn rotate90(self: &mut Self) { + if self.dx == 1 && self.dy == 0 { + self.dx = 0; + self.dy = 1; + } else if self.dx == 0 && self.dy == 1 { + self.dx = -1; + self.dy = 0; + } else if self.dx == -1 && self.dy == 0 { + self.dx = 0; + self.dy = -1; + } else if self.dx == 0 && self.dy == -1 { + self.dx = 1; + self.dy = 0; + } else { + panic!("Cannot rotate this orientation."); + } + } + + pub fn forward(self: &mut Self) { + self.x = (self.x as isize + self.dx) as usize; + self.y = (self.y as isize + self.dy) as usize; + } + + pub fn front(self: &mut Self) -> (isize, isize) { + (self.x as isize + self.dx, self.y as isize + self.dy) + } +} + + +fn guardian_coverage(obstacles: &Vec>, guard: &mut Guardian) -> Vec> { + let mut covered: Vec> = vec![vec![false; obstacles[0].len()]; obstacles.len()]; + covered[guard.y][guard.x] = true; + let bound_x = obstacles[0].len() as isize; + let bound_y = obstacles.len() as isize; + loop { + let (x, y) = guard.front(); + if x < 0 || y < 0 || x >= bound_x || y >= bound_y { + break; + } else { + let x = x as usize; + let y = y as usize; + if obstacles[y][x] { + guard.rotate90(); + } else { + covered[y][x] = true; + guard.forward(); + } + } + } + covered +} + +fn number_of_true(grid: &Vec>) -> u64 { + let mut count = 0; + for row in grid { + for item in row { + if *item { + count += 1; + } + } + } + count +} + +fn main() -> std::io::Result<()>{ + let mut obstacles: Vec> = Vec::new(); + let mut guard: Guardian = Guardian::new(0, 0); + let mut y: usize = 0; + for line in std::io::stdin().lines() { + let line: String = line.unwrap(); + let mut obstacles_row: Vec = Vec::new(); + let mut x: usize = 0; + for letter in line.chars() { + if letter == '^' { + guard = Guardian::new(x, y); + obstacles_row.push(false); + } else if letter == '#' { + obstacles_row.push(true); + } else { + obstacles_row.push(false); + } + x += 1; + } + obstacles.push(obstacles_row); + y += 1; + } + let coverage = guardian_coverage(&obstacles, &mut guard); + let covered = number_of_true(&coverage); + println!("{}", covered); + Ok(()) +} diff --git a/2024/days/06/part2/Cargo.toml b/2024/days/06/part2/Cargo.toml new file mode 100644 index 0000000..6bd04ba --- /dev/null +++ b/2024/days/06/part2/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day06" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/2024/days/06/part2/src/main.rs b/2024/days/06/part2/src/main.rs new file mode 100644 index 0000000..ebccded --- /dev/null +++ b/2024/days/06/part2/src/main.rs @@ -0,0 +1,115 @@ +use std::collections::BTreeSet; + + +struct Guardian { + x: usize, + y: usize, + dx: isize, + dy: isize, +} + +impl Guardian { + pub fn new(x: usize, y: usize) -> Self { + let dx = 0; + let dy = -1; + Guardian{ x, y, dx, dy } + } + + pub fn rotate90(self: &mut Self) { + if self.dx == 1 && self.dy == 0 { + self.dx = 0; + self.dy = 1; + } else if self.dx == 0 && self.dy == 1 { + self.dx = -1; + self.dy = 0; + } else if self.dx == -1 && self.dy == 0 { + self.dx = 0; + self.dy = -1; + } else if self.dx == 0 && self.dy == -1 { + self.dx = 1; + self.dy = 0; + } else { + panic!("Cannot rotate this orientation."); + } + } + + pub fn forward(self: &mut Self) { + self.x = (self.x as isize + self.dx) as usize; + self.y = (self.y as isize + self.dy) as usize; + } + + pub fn front(self: &mut Self) -> (isize, isize) { + (self.x as isize + self.dx, self.y as isize + self.dy) + } +} + + +fn is_stuck_in_loop(obstacles: &Vec>, x: usize, y: usize, supplement_obstacle_x: usize, supplement_obstacle_y: usize) -> bool { + let mut visited: BTreeSet<(usize, usize, isize, isize)> = BTreeSet::new(); + let bound_x = obstacles[0].len() as isize; + let bound_y = obstacles.len() as isize; + let mut guard: Guardian = Guardian::new(x, y); + loop { + if visited.contains(&(guard.x, guard.y, guard.dx, guard.dy)) { + return true; + } else { + visited.insert((guard.x, guard.y, guard.dx, guard.dy)); + } + let (x, y) = guard.front(); + if x < 0 || y < 0 || x >= bound_x || y >= bound_y { + break; + } else { + let x = x as usize; + let y = y as usize; + if obstacles[y][x] || supplement_obstacle_x == x && supplement_obstacle_y == y { + guard.rotate90(); + } else { + guard.forward(); + } + } + } + return false; +} + + + +fn find_loops(guard: Guardian, obstacles: &Vec>) -> u64 { + let mut count: u64 = 0; + for i in 0..obstacles.len() { + for j in 0..obstacles.len() { + if !obstacles[i][j] { + if is_stuck_in_loop(obstacles, guard.x, guard.y, j, i) { + count += 1; + } + } + } + } + count +} + +fn main() -> std::io::Result<()>{ + let mut obstacles: Vec> = Vec::new(); + let mut guard: Guardian = Guardian::new(0, 0); + let mut y: usize = 0; + for line in std::io::stdin().lines() { + let line: String = line.unwrap(); + let mut obstacles_row: Vec = Vec::new(); + let mut x: usize = 0; + for letter in line.chars() { + if letter == '^' { + guard = Guardian::new(x, y); + obstacles_row.push(false); + } else if letter == '#' { + obstacles_row.push(true); + } else { + obstacles_row.push(false); + } + x += 1; + } + obstacles.push(obstacles_row); + y += 1; + } + let loops: u64 = find_loops(guard, &obstacles); + println!("{}", loops); + Ok(()) +}