day 11: add A*
this is slower than BFS. See Claude for possible reasoning
This commit is contained in:
+51
-3
@@ -1,10 +1,13 @@
|
||||
use std::collections::{BTreeSet, HashSet, VecDeque};
|
||||
use std::{
|
||||
cmp::Reverse,
|
||||
collections::{BTreeSet, BinaryHeap, HashSet, VecDeque},
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
fn main() {
|
||||
part_1(); // 33
|
||||
part_2();
|
||||
part_2(); // 57
|
||||
}
|
||||
|
||||
fn part_2() {
|
||||
@@ -19,7 +22,7 @@ fn part_1() {
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
struct State {
|
||||
floors: [BTreeSet<Item>; 4],
|
||||
elevator: usize,
|
||||
@@ -150,6 +153,17 @@ impl State {
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn heuristic(&self) -> usize {
|
||||
self.floors
|
||||
.iter()
|
||||
.take(3)
|
||||
.rev()
|
||||
.zip(1..=3)
|
||||
.map(|(set, distance)| set.len() * distance)
|
||||
.sum::<usize>()
|
||||
/ 2
|
||||
}
|
||||
}
|
||||
|
||||
fn floor_is_valid(floor: &BTreeSet<Item>) -> bool {
|
||||
@@ -190,3 +204,37 @@ fn bfs(start: State) -> usize {
|
||||
}
|
||||
panic!("goal state unreachable");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn a_star(start: State) -> usize {
|
||||
let mut heap: BinaryHeap<_> = BinaryHeap::new();
|
||||
|
||||
let mut visited = HashSet::new();
|
||||
|
||||
heap.push(Reverse((start.heuristic(), 0_usize, start)));
|
||||
|
||||
while let Some(Reverse((_, distance, current_state))) = heap.pop() {
|
||||
if visited.contains(¤t_state) {
|
||||
continue;
|
||||
} else {
|
||||
visited.insert(current_state.clone());
|
||||
}
|
||||
|
||||
if current_state.is_goal_state() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
for state in current_state.neighbors() {
|
||||
if visited.contains(&state) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let heuristic = state.heuristic();
|
||||
let new_distance = distance + 1;
|
||||
// f_score = g_score + h_score
|
||||
// = distance + heuristic;
|
||||
heap.push(Reverse((distance + heuristic, new_distance, state)));
|
||||
}
|
||||
}
|
||||
panic!("goal state unreachable");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user