Let's solve one by one.

A1. Yes. Just define a trait and impletement it for `Vec<T>`

.

```
trait Distributable {
fn distribute(&mut self);
}
impl<T: Clone + std::cmp::Eq + std::hash::Hash + std::fmt::Debug> Distributable for Vec<T> {
fn distribute(&mut self) {
#[derive(Debug, Clone)]
struct PrioItem<K> {
value: K, // The actual item in the list
count: usize, // Count of items in the list
freq: f64, // Kind of a frequency with which it will appear in the reordered list
prio: f64, // Priority with which the this item should be placed next while building the reordered list
}
/// Puts a PrioItem on the Priority heap. The position of insertion of the heap is determined by the priority value
fn put_on_heap<K>(heap: &mut Vec::<PrioItem<K>>, item: PrioItem<K>) {
let mut idx = heap.len();
heap.push(item);
while idx > 0 {
if heap[idx].prio > heap[idx-1].prio || (heap[idx].prio == heap[idx-1].prio && heap[idx].freq <= heap[idx-1].freq) {
heap.swap(idx, idx-1);
}
idx -= 1;
}
}
// Create a list of the Items and their count, priority, ... such that the
// last element of the list is the next item to be placed
let mut prioheap = Vec::<PrioItem<T>>::new();
for ival in remove_duplicates(self.to_vec()).iter() {
let value = ival;
let count = self.iter().filter(|x| *x == value).count();
let freq = self.len() as f64 / count as f64;
let prio = freq/2.0;
put_on_heap(&mut prioheap,
PrioItem {
value: value.clone(), count, freq, prio
});
}
// Empty the original list an rebuild it based on the priority heap
self.clear();
loop {
match prioheap.pop() {
Some(mut prioitem) => {
self.push(prioitem.value.clone());
prioitem.count -= 1;
prioitem.prio += prioitem.freq;
// Only put the Priority item back on the heap, if elements are left
if prioitem.count > 0 {
put_on_heap(&mut prioheap, prioitem);
}
},
None => break
}
}
}
}
#[test]
fn distribution() {
let mut list = vec![0,0,1,1,2,2];
list.distribute();
assert_eq!(list, vec![0,1,2,0,1,2]);
let mut list = vec![0,0,0,0,1,1,1,2,2,3];
list.distribute();
assert_eq!(list, vec![0,1,2,0,3,1,0,2,1,0]);
let mut list = vec![0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,0,0,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8,9,9,10,10,11,12,13,14];
list.distribute();
assert_eq!(list, vec![0,1,2,3,4,5,6,7,0,1,10,8,9,2,3,4,0,1,5,2,0,13,14,11,12,6,7,4,3,1,0,2,5,1,0,4,3,10,8,9,2,1,0,7,6,5,4,3,2,1,0]);
}
```

A2. I think it's good to keep details away from user.

A3. Maybe you can try this:

```
fn remove_duplicates<T>(mut list: Vec<T>) -> Vec<T> where T: Ord {
list.sort();
list.dedup();
list
}
```

Updated:

A4 & A5: There were some inefficient points which is mentioned by @jeanas, and the test case `distribution`

is too confusing to catch you. I don't think that's one extractly answer for distribute a vector most equally. Perhaps you could provide more details about what you wanna do.

I'm doing a project where I need the elements in a vector to be most equally distributed.