pre y2024d16p2
This commit is contained in:
parent
6e3d6625ee
commit
ff241d76cb
@ -1,4 +1,7 @@
|
|||||||
use std::{collections::HashMap, error::Error};
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
error::Error,
|
||||||
|
};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
@ -61,7 +64,75 @@ pub fn process_part1(input: &str) -> usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_part2(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)]
|
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
|
||||||
@ -101,11 +172,12 @@ enum ReindeerState {
|
|||||||
Stuck,
|
Stuck,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||||
struct Reindeer {
|
struct Reindeer {
|
||||||
orientation: Orientation,
|
orientation: Orientation,
|
||||||
coords: (usize, usize),
|
coords: (usize, usize),
|
||||||
score: usize,
|
score: usize,
|
||||||
|
visited: HashSet<(usize, usize)>,
|
||||||
state: ReindeerState,
|
state: ReindeerState,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,9 +195,12 @@ 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
|
..*self
|
||||||
}
|
}
|
||||||
} else if tile == GridTile::End {
|
} else if tile == GridTile::End {
|
||||||
@ -133,12 +208,14 @@ impl Reindeer {
|
|||||||
score: self.score + 1,
|
score: self.score + 1,
|
||||||
state: ReindeerState::Arrived,
|
state: ReindeerState::Arrived,
|
||||||
coords,
|
coords,
|
||||||
|
visited,
|
||||||
..*self
|
..*self
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Reindeer {
|
Reindeer {
|
||||||
score: self.score + 1,
|
score: self.score + 1,
|
||||||
coords,
|
coords,
|
||||||
|
visited,
|
||||||
..*self
|
..*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,9 +234,12 @@ 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
|
..*self
|
||||||
}
|
}
|
||||||
} else if tile == GridTile::End {
|
} else if tile == GridTile::End {
|
||||||
@ -168,12 +248,14 @@ impl Reindeer {
|
|||||||
state: ReindeerState::Arrived,
|
state: ReindeerState::Arrived,
|
||||||
coords,
|
coords,
|
||||||
orientation: self.orientation.turn_clockwise(),
|
orientation: self.orientation.turn_clockwise(),
|
||||||
|
visited,
|
||||||
}
|
}
|
||||||
} 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
|
..*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,9 +274,12 @@ 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
|
..*self
|
||||||
}
|
}
|
||||||
} else if tile == GridTile::End {
|
} else if tile == GridTile::End {
|
||||||
@ -203,12 +288,14 @@ impl Reindeer {
|
|||||||
state: ReindeerState::Arrived,
|
state: ReindeerState::Arrived,
|
||||||
coords,
|
coords,
|
||||||
orientation: self.orientation.turn_counterclockwise(),
|
orientation: self.orientation.turn_counterclockwise(),
|
||||||
|
visited,
|
||||||
}
|
}
|
||||||
} 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
|
..*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,8 +393,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part2() {
|
fn part2_1() {
|
||||||
let result = process_part2(INPUT_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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user