This commit is contained in:
StNicolay 2024-12-06 17:16:21 +03:00
parent 94e2a83fd6
commit 68152e225f
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
2 changed files with 127 additions and 2 deletions

124
src/day6.rs Normal file

@ -0,0 +1,124 @@
use std::collections::HashSet;
#[derive(PartialEq, Eq)]
enum Position {
Occupied,
Free,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
enum Direction {
Up,
Down,
Left,
Right,
}
impl Direction {
fn rotate(self) -> Self {
match self {
Self::Up => Self::Right,
Self::Right => Self::Down,
Self::Down => Self::Left,
Self::Left => Self::Up,
}
}
fn next(
self,
mut current: (usize, usize),
dimentions: (usize, usize),
) -> Option<(usize, usize)> {
match self {
Self::Up => current.0 = current.0.checked_sub(1)?,
Self::Down => current.0 += 1,
Self::Left => current.1 = current.1.checked_sub(1)?,
Self::Right => current.1 += 1,
}
if current.0 >= dimentions.0 || current.1 >= dimentions.1 {
return None;
}
Some(current)
}
}
fn parse_board(data: &str) -> (Vec<Vec<Position>>, (usize, usize)) {
let mut position = None;
let board = data
.lines()
.enumerate()
.map(|(i, line)| {
line.bytes()
.enumerate()
.map(|(j, b)| match b {
b'#' => Position::Occupied,
b'.' => Position::Free,
b'^' => {
position = Some((i, j));
Position::Free
}
byte => unreachable!("{}", byte as char),
})
.collect()
})
.collect();
(board, position.expect("User pos not found"))
}
fn get_visited(board: &[Vec<Position>], mut pos: (usize, usize)) -> HashSet<(usize, usize)> {
let mut visited = HashSet::new();
let mut direction = Direction::Up;
let dimentions = (board.len(), board[1].len());
loop {
let Some(p) = direction.next(pos, dimentions) else {
break;
};
if board[p.0][p.1] == Position::Occupied {
direction = direction.rotate();
continue;
}
pos = p;
visited.insert(p);
}
visited
}
pub fn task1() {
let (board, pos) = parse_board(&std::fs::read_to_string("input.txt").unwrap());
let mut visited = get_visited(&board, pos);
visited.insert(pos);
println!("{}", visited.len());
}
fn is_loop(board: &[Vec<Position>], mut pos: (usize, usize)) -> bool {
let mut visited = HashSet::new();
let mut direction = Direction::Up;
let dimentions = (board.len(), board[1].len());
loop {
let Some(p) = direction.next(pos, dimentions) else {
return false;
};
if board[p.0][p.1] == Position::Occupied {
direction = direction.rotate();
continue;
}
pos = p;
if !visited.insert((pos, direction)) {
return true;
}
}
}
pub fn task2() {
let (mut board, pos) = parse_board(&std::fs::read_to_string("input.txt").unwrap());
let visited = get_visited(&board, pos);
let mut c: usize = 0;
for (a, b) in visited {
board[a][b] = Position::Occupied;
if is_loop(&board, pos) {
c += 1;
}
board[a][b] = Position::Free;
}
println!("{c}");
}

@ -3,6 +3,7 @@ mod day2;
mod day3;
mod day4;
mod day5;
mod day6;
use std::{
fs::File,
@ -20,6 +21,6 @@ fn parse_line(line: &str, pattern: char) -> impl Iterator<Item = i32> + '_ {
}
fn main() {
day5::task1();
day5::task2();
day6::task1();
day6::task2();
}