Day 6
This commit is contained in:
parent
94e2a83fd6
commit
68152e225f
124
src/day6.rs
Normal file
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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user