/*
Ranking elements of an integer vector based on sorted order in Rust
-------------------------------------------------------------------
Ranking rules:
- Lowest value gets rank 1
- Equal values share the same rank
- Rank increases only when encountering a new unique value
*/
use std::collections::HashMap;
// ------------------------------------------------------------
// Function 1: Print the vector
// ------------------------------------------------------------
fn print_vec(vec: &Vec<i32>) {
println!("Vector: {:?}", vec);
}
// ------------------------------------------------------------
// Function 2: Create a copy of the vector
// ------------------------------------------------------------
fn copy_vec(vec: &Vec<i32>) -> Vec<i32> {
vec.clone()
}
// ------------------------------------------------------------
// Function 3: Sort the vector copy
// ------------------------------------------------------------
fn sort_vec(vec_copy: &mut Vec<i32>) {
vec_copy.sort();
}
// ------------------------------------------------------------
// Function 4: Build a map of value → rank
// ------------------------------------------------------------
fn build_rank_map(sorted_vec: &Vec<i32>) -> HashMap<i32, i32> {
let mut map: HashMap<i32, i32> = HashMap::new();
if sorted_vec.is_empty() {
return map;
}
let mut rank: i32 = 1;
let mut previous: i32 = sorted_vec[0];
map.insert(previous, rank);
for i in 1..sorted_vec.len() {
let current: i32 = sorted_vec[i];
if current != previous {
rank += 1;
}
map.insert(current, rank);
previous = current;
}
map
}
// ------------------------------------------------------------
// Function 5: Apply ranks to original vector order
// ------------------------------------------------------------
fn apply_ranks(original: &Vec<i32>, rank_map: &HashMap<i32, i32>) -> Vec<i32> {
let mut ranked: Vec<i32> = Vec::with_capacity(original.len());
for value in original {
ranked.push(*rank_map.get(value).unwrap());
}
ranked
}
// ------------------------------------------------------------
// Main ranking function
// ------------------------------------------------------------
fn rank_vec(vec: &Vec<i32>) {
print_vec(vec);
if vec.is_empty() {
return;
}
let mut vec_copy: Vec<i32> = copy_vec(vec);
sort_vec(&mut vec_copy);
let rank_map: HashMap<i32, i32> = build_rank_map(&vec_copy);
let ranked: Vec<i32> = apply_ranks(vec, &rank_map);
println!("Rank: {:?}", ranked);
}
// ------------------------------------------------------------
// MAIN PROGRAM
// ------------------------------------------------------------
fn main() {
let vec: Vec<i32> = vec![33, 99, 10, 25, 47, 11, 77];
rank_vec(&vec);
}
/*
run:
Vector: [33, 99, 10, 25, 47, 11, 77]
Rank: [4, 7, 1, 3, 5, 2, 6]
*/