day 11: add A*

this is slower than BFS. See Claude for possible reasoning
This commit is contained in:
timeshifter
2026-07-01 18:29:17 +02:00
parent bd36a0af12
commit adbe41f067
+51 -3
View File
@@ -1,10 +1,13 @@
use std::collections::{BTreeSet, HashSet, VecDeque}; use std::{
cmp::Reverse,
collections::{BTreeSet, BinaryHeap, HashSet, VecDeque},
};
use itertools::Itertools; use itertools::Itertools;
fn main() { fn main() {
part_1(); // 33 part_1(); // 33
part_2(); part_2(); // 57
} }
fn part_2() { fn part_2() {
@@ -19,7 +22,7 @@ fn part_1() {
println!("{result}"); println!("{result}");
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct State { struct State {
floors: [BTreeSet<Item>; 4], floors: [BTreeSet<Item>; 4],
elevator: usize, elevator: usize,
@@ -150,6 +153,17 @@ impl State {
result 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 { fn floor_is_valid(floor: &BTreeSet<Item>) -> bool {
@@ -190,3 +204,37 @@ fn bfs(start: State) -> usize {
} }
panic!("goal state unreachable"); 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(&current_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");
}