I’m studying Rust by Exercism → Rust → Exercises. I’m stuck on “Two Bucket”, but I don’t know what’s wrong with my Breadth First Search algorithm solution for the exercise. The solution I found seems correct, but I don’t pass the tests. Can anyone help?
use std::collections::{HashMap, LinkedList};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Bucket {
One,
Two,
}
#[derive(PartialEq, Eq, Debug)]
pub struct BucketStats {
pub moves: u8,
pub goal_bucket: Bucket,
pub other_bucket: u8,
}
// It’s a Breadth First Search algorithm implementation
pub fn solve(
capacity_1: u8,
capacity_2: u8,
goal: u8,
start_bucket: &Bucket,
) → Option {
let initial = match *start_bucket {
Bucket::One => NodeState::new(capacity_1, 0),
Bucket::Two => NodeState::new(0, capacity_2),
};
let mut visited = HashMap::new();
let mut queue = LinkedList::new();
visited.insert(NodeState::ZERO_STATE, 0);
visited.insert(initial, 1);
queue.push_front(initial);
while let Some(current) = queue.pop_back() {
let moves = *visited.get(¤t).unwrap();
if current.bucket_1 == goal || current.bucket_2 == goal {
let (target, other) = if current.bucket_1 == goal {
(Bucket::One, current.bucket_2)
} else {
(Bucket::Two, current.bucket_1)
};
return Some(BucketStats {
moves: moves,
goal_bucket: target,
other_bucket: other,
});
}
current.sucessors(capacity_1, capacity_2)
.iter()
.cloned()
.for_each(|s| {
if !visited.contains_key(&s) {
visited.insert(s, moves + 1);
queue.push_front(s);
}
});
}
None
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
struct NodeState {
bucket_1: u8,
bucket_2: u8,
}
impl NodeState {
pub const ZERO_STATE: NodeState = NodeState::new(0, 0);
pub const fn new(bucket_1: u8, bucket_2: u8) -> Self {
NodeState {
bucket_1: bucket_1,
bucket_2: bucket_2,
}
}
pub fn sucessors(&self, capacity_1: u8, capacity_2: u8) -> Vec<NodeState> {
let mut container = Vec::new();
let buck1 = self.bucket_1;
let buck2 = self.bucket_2;
if buck1 < capacity_1 {
container.push( NodeState::new(capacity_1, buck2) );
}
if buck2 < capacity_2 {
container.push( NodeState::new(buck1, capacity_2) );
}
if buck1 > 0 {
container.push( NodeState::new(0, buck2) );
}
if buck2 > 0 {
container.push( NodeState::new(buck1, 0) );
}
if buck1 > 0 && buck2 < capacity_2 {
let remainder = capacity_2 - buck2;
if buck1 > remainder {
container.push( NodeState::new(buck1 - remainder, capacity_2) );
} else {
container.push( NodeState::new(0, buck1 + buck2) );
}
}
if buck2 > 0 && buck1 < capacity_1 {
let remainder = capacity_1 - buck1;
if buck2 > remainder {
container.push( NodeState::new(capacity_1, buck2 - remainder) );
} else {
container.push( NodeState::new(buck1 + buck2, 0) );
}
}
container
}
}