y2024d16p2
This commit is contained in:
parent
ff241d76cb
commit
e55dcd47a3
@ -1,7 +1,4 @@
|
|||||||
use std::{
|
use std::{collections::HashMap, error::Error};
|
||||||
collections::{HashMap, HashSet},
|
|
||||||
error::Error,
|
|
||||||
};
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
@ -37,6 +34,7 @@ pub fn process_part1(input: &str) -> usize {
|
|||||||
}];
|
}];
|
||||||
let mut arrived: Vec<Reindeer> = Vec::new();
|
let mut arrived: Vec<Reindeer> = Vec::new();
|
||||||
let mut visited = HashMap::new();
|
let mut visited = HashMap::new();
|
||||||
|
let mut iter = 0;
|
||||||
while !next_paths.is_empty() {
|
while !next_paths.is_empty() {
|
||||||
next_paths = next_paths
|
next_paths = next_paths
|
||||||
.iter()
|
.iter()
|
||||||
@ -59,7 +57,9 @@ pub fn process_part1(input: &str) -> usize {
|
|||||||
arrived.push(arrived_reindeer);
|
arrived.push(arrived_reindeer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iter += 1;
|
||||||
}
|
}
|
||||||
|
println!("Iterations to goal {iter}");
|
||||||
arrived.iter().map(|reindeer| reindeer.score).min().unwrap()
|
arrived.iter().map(|reindeer| reindeer.score).min().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,15 +89,15 @@ pub fn process_part2(input: &str) -> usize {
|
|||||||
.collect_vec()
|
.collect_vec()
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
let mut visited = HashSet::new();
|
let mut smallest_score = usize::MAX;
|
||||||
visited.insert(start);
|
let mut visited = HashMap::new();
|
||||||
|
visited.insert((start, Orientation::East), 0);
|
||||||
let mut next_paths = vec![Reindeer {
|
let mut next_paths = vec![Reindeer {
|
||||||
coords: start,
|
coords: start,
|
||||||
visited,
|
visited: visited.clone(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}];
|
}];
|
||||||
let mut arrived: Vec<Reindeer> = Vec::new();
|
let mut arrived: Vec<Reindeer> = Vec::new();
|
||||||
let mut visited = HashMap::new();
|
|
||||||
while !next_paths.is_empty() {
|
while !next_paths.is_empty() {
|
||||||
next_paths = next_paths
|
next_paths = next_paths
|
||||||
.iter()
|
.iter()
|
||||||
@ -105,33 +105,47 @@ pub fn process_part2(input: &str) -> usize {
|
|||||||
.collect_vec()
|
.collect_vec()
|
||||||
.concat();
|
.concat();
|
||||||
for (idx, reindeer) in next_paths.clone().iter().enumerate().rev() {
|
for (idx, reindeer) in next_paths.clone().iter().enumerate().rev() {
|
||||||
if let Some(_score) = visited.get_mut(&reindeer.coords) {
|
if reindeer.score > smallest_score
|
||||||
//if *score < reindeer.score {
|
|| reindeer
|
||||||
// next_paths.remove(idx);
|
.visited
|
||||||
// continue;
|
.contains_key(&(reindeer.coords, reindeer.orientation))
|
||||||
//} else {
|
{
|
||||||
// *score = reindeer.score;
|
next_paths.remove(idx);
|
||||||
//}
|
continue;
|
||||||
} else {
|
|
||||||
visited.insert(reindeer.coords, reindeer.score);
|
|
||||||
}
|
}
|
||||||
if reindeer.state == ReindeerState::Arrived {
|
next_paths[idx]
|
||||||
|
.visited
|
||||||
|
.insert((reindeer.coords, reindeer.orientation), reindeer.score);
|
||||||
|
if let Some(score) = visited.get_mut(&(reindeer.coords, reindeer.orientation)) {
|
||||||
|
if *score < reindeer.score {
|
||||||
|
next_paths.remove(idx);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
*score = reindeer.score;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
visited.insert((reindeer.coords, reindeer.orientation), reindeer.score);
|
||||||
|
}
|
||||||
|
if reindeer.state == ReindeerState::Arrived && reindeer.score <= smallest_score {
|
||||||
|
smallest_score = reindeer.score;
|
||||||
let arrived_reindeer = next_paths.remove(idx);
|
let arrived_reindeer = next_paths.remove(idx);
|
||||||
arrived.push(arrived_reindeer);
|
arrived.push(arrived_reindeer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
arrived.retain(|reindeer| reindeer.score == smallest_score);
|
||||||
}
|
}
|
||||||
let min_score = arrived.iter().map(|reindeer| reindeer.score).min().unwrap();
|
|
||||||
let visited = arrived
|
let visited = arrived
|
||||||
.into_iter()
|
.iter()
|
||||||
.filter(|reindeer| reindeer.score == min_score)
|
.map(|reindeer| {
|
||||||
.collect_vec();
|
reindeer
|
||||||
println!("{visited:?}");
|
.visited
|
||||||
let visited = visited
|
.keys()
|
||||||
.into_iter()
|
.map(|(coords, _)| coords)
|
||||||
.map(|reindeer| reindeer.visited.into_iter().collect_vec())
|
.collect_vec()
|
||||||
|
})
|
||||||
.collect_vec()
|
.collect_vec()
|
||||||
.concat();
|
.concat();
|
||||||
|
log_maze(&grid, &arrived);
|
||||||
visited.iter().unique().count()
|
visited.iter().unique().count()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +191,7 @@ struct Reindeer {
|
|||||||
orientation: Orientation,
|
orientation: Orientation,
|
||||||
coords: (usize, usize),
|
coords: (usize, usize),
|
||||||
score: usize,
|
score: usize,
|
||||||
visited: HashSet<(usize, usize)>,
|
visited: HashMap<((usize, usize), Orientation), usize>,
|
||||||
state: ReindeerState,
|
state: ReindeerState,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,28 +209,23 @@ impl Reindeer {
|
|||||||
Orientation::South => (self.coords.0, self.coords.1 + 1),
|
Orientation::South => (self.coords.0, self.coords.1 + 1),
|
||||||
Orientation::North => (self.coords.0, self.coords.1 - 1),
|
Orientation::North => (self.coords.0, self.coords.1 - 1),
|
||||||
};
|
};
|
||||||
let mut visited = self.visited.clone();
|
|
||||||
visited.insert(coords);
|
|
||||||
if tile == GridTile::Wall {
|
if tile == GridTile::Wall {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
state: ReindeerState::Stuck,
|
state: ReindeerState::Stuck,
|
||||||
visited,
|
..self.clone()
|
||||||
..*self
|
|
||||||
}
|
}
|
||||||
} else if tile == GridTile::End {
|
} else if tile == GridTile::End {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
score: self.score + 1,
|
score: self.score + 1,
|
||||||
state: ReindeerState::Arrived,
|
state: ReindeerState::Arrived,
|
||||||
coords,
|
coords,
|
||||||
visited,
|
..self.clone()
|
||||||
..*self
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
score: self.score + 1,
|
score: self.score + 1,
|
||||||
coords,
|
coords,
|
||||||
visited,
|
..self.clone()
|
||||||
..*self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,13 +243,10 @@ impl Reindeer {
|
|||||||
Orientation::South => (self.coords.0 - 1, self.coords.1),
|
Orientation::South => (self.coords.0 - 1, self.coords.1),
|
||||||
Orientation::North => (self.coords.0 + 1, self.coords.1),
|
Orientation::North => (self.coords.0 + 1, self.coords.1),
|
||||||
};
|
};
|
||||||
let mut visited = self.visited.clone();
|
|
||||||
visited.insert(coords);
|
|
||||||
if tile == GridTile::Wall {
|
if tile == GridTile::Wall {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
state: ReindeerState::Stuck,
|
state: ReindeerState::Stuck,
|
||||||
visited,
|
..self.clone()
|
||||||
..*self
|
|
||||||
}
|
}
|
||||||
} else if tile == GridTile::End {
|
} else if tile == GridTile::End {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
@ -248,15 +254,14 @@ impl Reindeer {
|
|||||||
state: ReindeerState::Arrived,
|
state: ReindeerState::Arrived,
|
||||||
coords,
|
coords,
|
||||||
orientation: self.orientation.turn_clockwise(),
|
orientation: self.orientation.turn_clockwise(),
|
||||||
visited,
|
..self.clone()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
score: self.score + 1001,
|
score: self.score + 1001,
|
||||||
orientation: self.orientation.turn_clockwise(),
|
orientation: self.orientation.turn_clockwise(),
|
||||||
coords,
|
coords,
|
||||||
visited,
|
..self.clone()
|
||||||
..*self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,13 +279,10 @@ impl Reindeer {
|
|||||||
Orientation::South => (self.coords.0 + 1, self.coords.1),
|
Orientation::South => (self.coords.0 + 1, self.coords.1),
|
||||||
Orientation::North => (self.coords.0 - 1, self.coords.1),
|
Orientation::North => (self.coords.0 - 1, self.coords.1),
|
||||||
};
|
};
|
||||||
let mut visited = self.visited.clone();
|
|
||||||
visited.insert(coords);
|
|
||||||
if tile == GridTile::Wall {
|
if tile == GridTile::Wall {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
state: ReindeerState::Stuck,
|
state: ReindeerState::Stuck,
|
||||||
visited,
|
..self.clone()
|
||||||
..*self
|
|
||||||
}
|
}
|
||||||
} else if tile == GridTile::End {
|
} else if tile == GridTile::End {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
@ -288,15 +290,14 @@ impl Reindeer {
|
|||||||
state: ReindeerState::Arrived,
|
state: ReindeerState::Arrived,
|
||||||
coords,
|
coords,
|
||||||
orientation: self.orientation.turn_counterclockwise(),
|
orientation: self.orientation.turn_counterclockwise(),
|
||||||
visited,
|
..self.clone()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
score: self.score + 1001,
|
score: self.score + 1001,
|
||||||
orientation: self.orientation.turn_counterclockwise(),
|
orientation: self.orientation.turn_counterclockwise(),
|
||||||
coords,
|
coords,
|
||||||
visited,
|
..self.clone()
|
||||||
..*self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,6 +343,47 @@ impl TryFrom<char> for GridTile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn log_maze(grid: &[Vec<GridTile>], visited: &Vec<Reindeer>) {
|
||||||
|
for (yidx, row) in grid.iter().enumerate() {
|
||||||
|
for (xidx, tile) in row.iter().enumerate() {
|
||||||
|
let contains = {
|
||||||
|
let mut contains = false;
|
||||||
|
for reindeer in visited {
|
||||||
|
if reindeer
|
||||||
|
.visited
|
||||||
|
.contains_key(&((xidx, yidx), Orientation::East))
|
||||||
|
|| reindeer
|
||||||
|
.visited
|
||||||
|
.contains_key(&((xidx, yidx), Orientation::West))
|
||||||
|
|| reindeer
|
||||||
|
.visited
|
||||||
|
.contains_key(&((xidx, yidx), Orientation::North))
|
||||||
|
|| reindeer
|
||||||
|
.visited
|
||||||
|
.contains_key(&((xidx, yidx), Orientation::South))
|
||||||
|
{
|
||||||
|
contains = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contains
|
||||||
|
};
|
||||||
|
if contains && !(*tile == GridTile::Start || *tile == GridTile::End) {
|
||||||
|
print!("O");
|
||||||
|
} else if *tile == GridTile::Wall {
|
||||||
|
print!("#");
|
||||||
|
} else if *tile == GridTile::Path {
|
||||||
|
print!(".");
|
||||||
|
} else if *tile == GridTile::Start {
|
||||||
|
print!("S");
|
||||||
|
} else if *tile == GridTile::End {
|
||||||
|
print!("E");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user