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 day3;
|
||||||
mod day4;
|
mod day4;
|
||||||
mod day5;
|
mod day5;
|
||||||
|
mod day6;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
@ -20,6 +21,6 @@ fn parse_line(line: &str, pattern: char) -> impl Iterator<Item = i32> + '_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
day5::task1();
|
day6::task1();
|
||||||
day5::task2();
|
day6::task2();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user