pre y2024d16p2

This commit is contained in:
Fabian Schmidt 2024-12-16 20:27:25 +01:00
parent 6e3d6625ee
commit ff241d76cb

View File

@ -1,4 +1,7 @@
use std::{collections::HashMap, error::Error};
use std::{
collections::{HashMap, HashSet},
error::Error,
};
use itertools::Itertools;
@ -61,7 +64,75 @@ pub fn process_part1(input: &str) -> usize {
}
pub fn process_part2(input: &str) -> usize {
0
let mut start = (0, 0);
let mut end = (0, 0);
let grid = input
.lines()
.enumerate()
.map(|(yidx, row)| {
row.chars()
.enumerate()
.map(|(xidx, chara)| {
let tile = GridTile::try_from(chara).unwrap();
match tile {
GridTile::Wall | GridTile::Path => tile,
GridTile::Start => {
start = (xidx, yidx);
tile
}
GridTile::End => {
end = (xidx, yidx);
tile
}
}
})
.collect_vec()
})
.collect_vec();
let mut visited = HashSet::new();
visited.insert(start);
let mut next_paths = vec![Reindeer {
coords: start,
visited,
..Default::default()
}];
let mut arrived: Vec<Reindeer> = Vec::new();
let mut visited = HashMap::new();
while !next_paths.is_empty() {
next_paths = next_paths
.iter()
.map(|reindeer| reindeer.get_all_next_paths(&grid))
.collect_vec()
.concat();
for (idx, reindeer) in next_paths.clone().iter().enumerate().rev() {
if let Some(_score) = visited.get_mut(&reindeer.coords) {
//if *score < reindeer.score {
// next_paths.remove(idx);
// continue;
//} else {
// *score = reindeer.score;
//}
} else {
visited.insert(reindeer.coords, reindeer.score);
}
if reindeer.state == ReindeerState::Arrived {
let arrived_reindeer = next_paths.remove(idx);
arrived.push(arrived_reindeer);
}
}
}
let min_score = arrived.iter().map(|reindeer| reindeer.score).min().unwrap();
let visited = arrived
.into_iter()
.filter(|reindeer| reindeer.score == min_score)
.collect_vec();
println!("{visited:?}");
let visited = visited
.into_iter()
.map(|reindeer| reindeer.visited.into_iter().collect_vec())
.collect_vec()
.concat();
visited.iter().unique().count()
}
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
@ -101,11 +172,12 @@ enum ReindeerState {
Stuck,
}
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
#[derive(Debug, Default, Clone, PartialEq, Eq)]
struct Reindeer {
orientation: Orientation,
coords: (usize, usize),
score: usize,
visited: HashSet<(usize, usize)>,
state: ReindeerState,
}
@ -123,9 +195,12 @@ impl Reindeer {
Orientation::South => (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 {
Reindeer {
state: ReindeerState::Stuck,
visited,
..*self
}
} else if tile == GridTile::End {
@ -133,12 +208,14 @@ impl Reindeer {
score: self.score + 1,
state: ReindeerState::Arrived,
coords,
visited,
..*self
}
} else {
Reindeer {
score: self.score + 1,
coords,
visited,
..*self
}
}
@ -157,9 +234,12 @@ impl Reindeer {
Orientation::South => (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 {
Reindeer {
state: ReindeerState::Stuck,
visited,
..*self
}
} else if tile == GridTile::End {
@ -168,12 +248,14 @@ impl Reindeer {
state: ReindeerState::Arrived,
coords,
orientation: self.orientation.turn_clockwise(),
visited,
}
} else {
Reindeer {
score: self.score + 1001,
orientation: self.orientation.turn_clockwise(),
coords,
visited,
..*self
}
}
@ -192,9 +274,12 @@ impl Reindeer {
Orientation::South => (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 {
Reindeer {
state: ReindeerState::Stuck,
visited,
..*self
}
} else if tile == GridTile::End {
@ -203,12 +288,14 @@ impl Reindeer {
state: ReindeerState::Arrived,
coords,
orientation: self.orientation.turn_counterclockwise(),
visited,
}
} else {
Reindeer {
score: self.score + 1001,
orientation: self.orientation.turn_counterclockwise(),
coords,
visited,
..*self
}
}
@ -306,8 +393,14 @@ mod tests {
}
#[test]
fn part2() {
fn part2_1() {
let result = process_part2(INPUT_1);
assert_eq!(result, 0);
assert_eq!(result, 45);
}
#[test]
fn part2_2() {
let result = process_part2(INPUT_2);
assert_eq!(result, 64);
}
}