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;
|
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(¤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