day_6: part 1 done
This commit is contained in:
73
src/advent_of_code/fri_06.rs
Normal file
73
src/advent_of_code/fri_06.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl Guard {
|
||||
fn step(&mut self, map: &FloorMap) -> IsGuardOut {
|
||||
let mut future_x = self.x;
|
||||
let mut future_y = self.y;
|
||||
|
||||
match self.dir {
|
||||
Direction::N => {
|
||||
if self.y == 0 {
|
||||
return true;
|
||||
}
|
||||
future_y -= 1
|
||||
}
|
||||
Direction::S => {
|
||||
if self.y == map.len() - 1 {
|
||||
return true;
|
||||
}
|
||||
future_y += 1
|
||||
}
|
||||
Direction::E => {
|
||||
if self.x == map[0].len() - 1 {
|
||||
return true;
|
||||
}
|
||||
future_x += 1;
|
||||
}
|
||||
Direction::W => {
|
||||
if self.x == 0 {
|
||||
return true;
|
||||
}
|
||||
future_x -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
match map[future_y][future_x] {
|
||||
Floor::Clear => {
|
||||
self.x = future_x;
|
||||
self.y = future_y;
|
||||
}
|
||||
Floor::Obstacle => {
|
||||
self.turn_90();
|
||||
return self.step(map);
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn turn_90(&mut self) {
|
||||
match self.dir {
|
||||
Direction::N => self.dir = Direction::E,
|
||||
Direction::S => self.dir = Direction::W,
|
||||
Direction::E => self.dir = Direction::S,
|
||||
Direction::W => self.dir = Direction::N,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn guard_gallivant(input: &str) -> PositionCount {
|
||||
let (mut the_guard, floor_map) = utils::read_floor_map_and_guard_input(input);
|
||||
|
||||
let mut visited_coordinates: HashSet<(usize, usize)> = HashSet::new();
|
||||
|
||||
// FIXME: this logic is not good enough, since the guard could walk on the same place twice, the second time should not be counted
|
||||
visited_coordinates.insert((the_guard.x, the_guard.y));
|
||||
while !the_guard.step(&floor_map) {
|
||||
visited_coordinates.insert((the_guard.x, the_guard.y));
|
||||
}
|
||||
|
||||
visited_coordinates.len()
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod fri_06;
|
||||
mod mon_02;
|
||||
mod sun_01;
|
||||
mod thu_05;
|
||||
@@ -46,4 +47,8 @@ pub fn historian_hysteria() {
|
||||
thu_05::mid_queue_sum("./assets/day_5_rules_queue_input");
|
||||
println!("The update mid-queue-sum is {}", queue_mid_sum);
|
||||
println!("The fixed update mid-queue-sum is {}", fixed_queue_mid_sum);
|
||||
|
||||
// Friday 06
|
||||
let guard_position_count = fri_06::guard_gallivant("./assets/day_6_guard_map_input");
|
||||
println!("The guard will visit {} positions", guard_position_count);
|
||||
}
|
||||
|
||||
@@ -23,3 +23,23 @@ pub type XMASCount = i32;
|
||||
// Print Queue
|
||||
pub struct Rule(pub u32, pub u32);
|
||||
pub type Queue = Vec<u32>;
|
||||
|
||||
// Guard Gallivant
|
||||
pub enum Direction {
|
||||
N,
|
||||
S,
|
||||
E,
|
||||
W,
|
||||
}
|
||||
pub enum Floor {
|
||||
Clear,
|
||||
Obstacle,
|
||||
}
|
||||
pub type PositionCount = usize;
|
||||
pub type IsGuardOut = bool;
|
||||
pub type FloorMap = Vec<Vec<Floor>>;
|
||||
pub struct Guard {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
pub dir: Direction,
|
||||
}
|
||||
|
||||
@@ -86,6 +86,45 @@ pub fn read_rules_and_queue(input: &str) -> (Vec<Rule>, Vec<Queue>) {
|
||||
(rules, queues)
|
||||
}
|
||||
|
||||
pub fn read_floor_map_and_guard_input(input: &str) -> (Guard, FloorMap) {
|
||||
let mut floor_map: FloorMap = vec![];
|
||||
let mut the_guard: Guard = Guard {
|
||||
x: 0,
|
||||
y: 0,
|
||||
dir: Direction::N,
|
||||
};
|
||||
|
||||
for (line_index, line) in read_to_string(input).unwrap().lines().enumerate() {
|
||||
let mut line_vec: Vec<Floor> = vec![];
|
||||
for (character_index, character) in line.chars().into_iter().enumerate() {
|
||||
match character {
|
||||
'.' => line_vec.push(Floor::Clear),
|
||||
'#' => line_vec.push(Floor::Obstacle),
|
||||
'>' | '<' | '^' | 'v' => {
|
||||
let guard_direction: Direction = {
|
||||
match character {
|
||||
'>' => Direction::E,
|
||||
'<' => Direction::W,
|
||||
'^' => Direction::N,
|
||||
'v' => Direction::S,
|
||||
_ => Direction::N,
|
||||
}
|
||||
};
|
||||
the_guard.dir = guard_direction;
|
||||
the_guard.x = character_index;
|
||||
the_guard.y = line_index;
|
||||
line_vec.push(Floor::Clear);
|
||||
}
|
||||
_ => line_vec.push(Floor::Obstacle),
|
||||
}
|
||||
}
|
||||
|
||||
floor_map.push(line_vec);
|
||||
}
|
||||
|
||||
(the_guard, floor_map)
|
||||
}
|
||||
|
||||
pub fn calc_distance<T>(num_1: T, num_2: T) -> T
|
||||
where
|
||||
T: PartialOrd + Sub<Output = T>,
|
||||
|
||||
Reference in New Issue
Block a user