d06 - but very inefficient

This commit is contained in:
JonOfUs 2024-12-06 15:25:17 +01:00
parent 18dc6dd714
commit 686ec4ed0e

View file

@ -1,7 +1,14 @@
use std::fs; use std::{
collections::{HashMap, HashSet},
fs,
};
use rayon::iter::{
IndexedParallelIterator, IntoParallelRefIterator, ParallelBridge, ParallelIterator,
};
pub fn solve() { pub fn solve() {
let path = "res/06/example"; let path = "res/06/input";
let contents = fs::read_to_string(path).expect("Something went wrong reading the file"); let contents = fs::read_to_string(path).expect("Something went wrong reading the file");
@ -17,22 +24,117 @@ pub fn solve() {
}) })
.collect(); .collect();
let mut pos: (usize, usize) = contents let init_pos: (isize, isize) = contents
.lines() .lines()
.enumerate() .enumerate()
.find(|(_, line)| line.contains("^")) .find(|(_, line)| line.contains("^"))
.map(|(x, line)| (x, line.chars().position(|c| c == '^').unwrap())) .map(|(x, line)| {
(
x as isize,
line.chars().position(|c| c == '^').unwrap() as isize,
)
})
.unwrap(); .unwrap();
let mut pos = init_pos;
let mut dir: (isize, isize) = (-1, 0); let mut dir: (isize, isize) = (-1, 0);
let mut guard_positions: Vec<(usize, usize)> = vec![]; let mut guard_positions: HashSet<(isize, isize)> = HashSet::new();
// let the guard move until he leaves the map // let the guard move until he leaves the map
while pos.0 >= 0 && pos.0 < map.len() as isize && pos.1 >= 0 && pos.1 < map[0].len() as isize {
// check if we need to turn right
if map[pos.0 as usize][pos.1 as usize] {
pos.0 = pos.0 - dir.0;
pos.1 = pos.1 - dir.1;
dir = match dir {
(-1, 0) => (0, 1),
(0, 1) => (1, 0),
(1, 0) => (0, -1),
(0, -1) => (-1, 0),
_ => panic!(),
};
}
let result: usize = 0; // add guard position
guard_positions.insert(pos);
// move guard
pos.0 += dir.0;
pos.1 += dir.1;
}
let result: usize = guard_positions.len();
println!("Result 1: {}", result); println!("Result 1: {}", result);
let mut obstacle_positions: HashSet<(isize, isize)> = HashSet::new();
let obstacle_positions: Vec<Vec<(isize, isize)>> = map
.iter()
.enumerate()
.par_bridge()
.map(|(i, row)| {
row.iter()
.enumerate()
.filter(|(j, cell)| {
if !*cell && (i as isize, *j as isize) != init_pos {
let mut new_map = map.clone();
new_map[i][*j] = true;
let mut dir: (isize, isize) = (-1, 0);
let mut pos = init_pos;
let mut positions: HashMap<(isize, isize), usize> = HashMap::new();
let mut cyclic = false;
while pos.0 >= 0
&& pos.0 < map.len() as isize
&& pos.1 >= 0
&& pos.1 < map[0].len() as isize
{
// check if we need to turn right
if new_map[pos.0 as usize][pos.1 as usize] {
pos.0 = pos.0 - dir.0;
pos.1 = pos.1 - dir.1;
dir = match dir {
(-1, 0) => (0, 1),
(0, 1) => (1, 0),
(1, 0) => (0, -1),
(0, -1) => (-1, 0),
_ => panic!(),
};
}
// move guard
pos.0 += dir.0;
pos.1 += dir.1;
if positions.contains_key(&pos) {
*positions.get_mut(&pos).unwrap() += 1;
} else {
positions.insert(pos, 1);
}
if *positions.get(&pos).unwrap() == 5 {
cyclic = true;
break;
}
}
if cyclic {
return true;
}
}
false
})
.map(|(j, _)| (i as isize, j as isize))
.collect()
})
.collect();
let obstacle_positions: HashSet<(isize, isize)> =
obstacle_positions.into_iter().flatten().collect();
let result: usize = obstacle_positions.len();
println!("Result 2: {}", result); println!("Result 2: {}", result);
} }