Fuck day6p2 lol
This commit is contained in:
parent
aecb2f2278
commit
c1e46e9f0d
1 changed files with 105 additions and 0 deletions
|
|
@ -1,4 +1,109 @@
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
const DIRECTIONS: [(i64, i64); 4] = [(0, -1), (1, 0), (0, 1), (-1, 0)]; // up right down left
|
||||||
|
|
||||||
|
fn find_start(grid: &[Vec<u8>]) -> (i64, i64) {
|
||||||
|
for (ypos, row) in grid.iter().enumerate() {
|
||||||
|
let Some(xpos) = row.iter().position(|ch| *ch == b'^') else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
return (xpos as i64, ypos as i64);
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("No starting position found");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn detect_loop(grid: &[Vec<u8>], start_pos: (i64, i64), start_dir: usize) -> (bool, HashSet<(i64, i64, usize)>) {
|
||||||
|
let width = grid[0].len() as i64;
|
||||||
|
let height = grid.len() as i64;
|
||||||
|
let mut position = start_pos;
|
||||||
|
let mut direction = start_dir;
|
||||||
|
|
||||||
|
let mut tensors: HashSet<(i64, i64, usize)> = HashSet::new();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
tensors.insert((position.0, position.1, direction));
|
||||||
|
|
||||||
|
let new_position = (position.0 + DIRECTIONS[direction].0, position.1 + DIRECTIONS[direction].1);
|
||||||
|
|
||||||
|
if new_position.0 < 0 || new_position.0 >= width || new_position.1 < 0 || new_position.1 >= height {
|
||||||
|
return (false, Default::default()); // new position is off the map, so no loop
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_direction = if grid[new_position.1 as usize][new_position.0 as usize] == b'#' {
|
||||||
|
(direction + 1) % DIRECTIONS.len()
|
||||||
|
} else {
|
||||||
|
direction
|
||||||
|
};
|
||||||
|
|
||||||
|
if tensors.contains(&(new_position.0, new_position.1, new_direction)) {
|
||||||
|
// we are at the exact same position again, so we are in a loop
|
||||||
|
return (true, tensors);
|
||||||
|
}
|
||||||
|
|
||||||
|
let next_step = grid[new_position.1 as usize][new_position.0 as usize];
|
||||||
|
if next_step == b'#' || next_step == b'@' {
|
||||||
|
direction = (direction + 1) % DIRECTIONS.len();
|
||||||
|
} else {
|
||||||
|
position = new_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_walked_grid(grid: &[Vec<u8>], steps: &HashSet<(i64, i64, usize)>) {
|
||||||
|
let steps = steps.iter().map(|tup| ((tup.0, tup.1), tup.2)).collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
|
for (ypos, line) in grid.iter().enumerate() {
|
||||||
|
for (xpos, step) in line.iter().enumerate() {
|
||||||
|
if *step == b'.' {
|
||||||
|
let pos = &(xpos as i64, ypos as i64);
|
||||||
|
if steps.contains_key(pos) {
|
||||||
|
let char = if steps.get(pos).unwrap() % 2 == 0 { "|" } else { "-" };
|
||||||
|
print!("{}", char);
|
||||||
|
} else {
|
||||||
|
print!(".");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print!("{}", *step as char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn solve(input: &str) {
|
pub fn solve(input: &str) {
|
||||||
|
let grid = input.lines().map(|line| line.as_bytes().to_vec()).collect::<Vec<_>>();
|
||||||
|
let width = grid[0].len() as i64;
|
||||||
|
let height = grid.len() as i64;
|
||||||
|
|
||||||
|
let start = find_start(&grid);
|
||||||
|
let start_dir = 0;
|
||||||
|
|
||||||
|
let mut position = start;
|
||||||
|
let mut direction = 0;
|
||||||
|
|
||||||
|
let mut looping_blockades = HashSet::new();
|
||||||
|
loop {
|
||||||
|
let new_position = (position.0 + DIRECTIONS[direction].0, position.1 + DIRECTIONS[direction].1);
|
||||||
|
if new_position.0 < 0 || new_position.0 >= width || new_position.1 < 0 || new_position.1 >= height {
|
||||||
|
break; // we're off the map
|
||||||
|
}
|
||||||
|
|
||||||
|
if new_position != start {
|
||||||
|
let mut test_grid = grid.clone();
|
||||||
|
test_grid[new_position.1 as usize][new_position.0 as usize] = b'@';
|
||||||
|
let (looped, steps) = detect_loop(&test_grid, start, start_dir);
|
||||||
|
if looped {
|
||||||
|
looping_blockades.insert(new_position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if grid[new_position.1 as usize][new_position.0 as usize] == b'#' {
|
||||||
|
direction = (direction + 1) % DIRECTIONS.len();
|
||||||
|
} else {
|
||||||
|
position = new_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Number of possible obstacles: {}", looping_blockades.len());
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue