eta_algorithms/
algorithms.rs

1use crate::data_structs::array::Array;
2use crate::data_structs::bitmap::Bitmap;
3use std::collections::{HashMap, HashSet};
4use std::hash::Hash;
5
6pub fn find_uniques<T>(values: &[T], values_hash: &mut HashMap<T, usize>) -> (u32, Bitmap)
7where
8    T: Copy + Sized + Hash + Eq,
9{
10    let mut bitmap = Bitmap::new(values.len());
11    let mut score = 0;
12    for (index, value) in values.iter().enumerate() {
13        if let Some(original_index) = values_hash.get(value) {
14            bitmap.set(*original_index, false);
15            continue;
16        }
17        values_hash.insert(*value, index);
18        bitmap.set(index, true);
19        score += 1;
20    }
21
22    (score, bitmap)
23}
24
25pub fn optimize_diversity<T>(existing_values: &[T], values: &[T]) -> Array<T>
26where
27    T: Copy + Sized + Hash + Eq,
28{
29    let mut top = values.len() - 1;
30    let mut hash_map = HashMap::with_capacity(existing_values.len());
31    let (_, bitmap) = find_uniques(existing_values, &mut hash_map);
32    let mut new_data = Array::from_slice(existing_values);
33    let accessible_indices = bitmap.to_indices_false();
34    for accessible_index in accessible_indices {
35        if top == 0 {
36            break;
37        }
38
39        let new_diversity = unsafe { values.get_unchecked(top) };
40        top -= 1;
41        if hash_map.contains_key(new_diversity) {
42            continue;
43        }
44        new_data[accessible_index] = *new_diversity;
45
46        hash_map.insert(*new_diversity, accessible_index);
47    }
48    new_data
49}
50
51pub fn extract_unique_pairs<T, U>(primary: &[T], secondary: &[U]) -> (Vec<T>, Vec<U>)
52where
53    T: Copy + Sized + Hash + Eq,
54    U: Copy + Sized + Hash + Eq,
55{
56    let mut primary_set = HashSet::<T>::with_capacity(primary.len());
57    let mut secondary_set = HashSet::<U>::with_capacity(secondary.len());
58    let mut pre_emptive_map = HashMap::<T, U>::with_capacity(primary.len());
59    let mut out_primary = Vec::<T>::with_capacity(primary.len());
60    let mut out_secondary = Vec::<U>::with_capacity(secondary.len());
61
62    for (primary, secondary) in primary.iter().zip(secondary) {
63        if !primary_set.contains(primary) {
64            if secondary_set.insert(*secondary) {
65                primary_set.insert(*primary);
66                out_primary.push(*primary);
67                out_secondary.push(*secondary);
68                pre_emptive_map.remove(primary);
69                continue;
70            }
71            pre_emptive_map.insert(*primary, *secondary);
72        }
73    }
74
75    for (primary, secondary) in pre_emptive_map {
76        out_primary.push(primary);
77        out_secondary.push(secondary);
78    }
79    (out_primary, out_secondary)
80}