How to select N unique random values that appear exactly once in an existing vector with Rust

1 Answer

0 votes
use rand::{rng, random_range};
use std::collections::HashMap;

/*
    Goal:
    - Select N random values that appear exactly once in the vector.
    - The vector includes duplicates, but only values with frequency = 1
      are eligible for selection.

    Approach:
    1. Count frequencies using a HashMap<i32, usize>.
    2. Collect values that appear exactly once.
    3. Shuffle the unique values using random_range().
    4. Take the first N values.
    5. Return them and print them.

    Notes:
    - Uses Rust's built-in tools for clarity and efficiency.
    - Uses structured, expressive functions.
*/

//---------------------------------------------------------------
// Build a frequency map: value -> count
//---------------------------------------------------------------
fn build_frequency_map(data: &[i32]) -> HashMap<i32, usize> {
    let mut freq: HashMap<i32, usize> = HashMap::new();

    for &value in data {
        *freq.entry(value).or_insert(0) += 1;
    }

    freq
}

//---------------------------------------------------------------
// Collect values that appear exactly once
//---------------------------------------------------------------
fn collect_globally_unique_values(data: &[i32], freq: &HashMap<i32, usize>) -> Vec<i32> {
    let mut unique: Vec<i32> = Vec::new();

    for &value in data {
        if freq.get(&value) == Some(&1) {
            unique.push(value);
        }
    }

    unique
}

//---------------------------------------------------------------
// Randomly select N values from the unique list
//---------------------------------------------------------------
fn select_random_unique(unique: &[i32], n: usize) -> Vec<i32> {
    let count: usize = unique.len();
    let n: usize = n.min(count);

    // Shuffle manually using random_range()
    let mut temp: Vec<i32> = unique.to_vec();
    let mut _rng = rng();

    for i in (1..temp.len()).rev() {
        let j: usize = random_range(0..=i);
        temp.swap(i, j);
    }

    temp.into_iter().take(n).collect()
}

//---------------------------------------------------------------
// Print helper
//---------------------------------------------------------------
fn print_vec(vec: &[i32]) {
    for v in vec {
        print!("{} ", v);
    }
    println!();
}

//---------------------------------------------------------------
// Main program
//---------------------------------------------------------------
fn main() {
    // Example vector with duplicates
    let data: Vec<i32> = vec![
        5, 12, 5, 19, 5, 33, 19, 5, 8, 8, 8, 59, 61, 17, 3, 5, 3, 74, 83, 90, 3, 1,
    ];

    // Step 1: Build frequency map
    let freq = build_frequency_map(&data);

    // Step 2: Collect values that appear exactly once
    let unique_values = collect_globally_unique_values(&data, &freq);

    // Step 3: Choose how many unique random values to select
    let n: usize = 5;

    // Step 4: Select N random unique values
    let random_selection = select_random_unique(&unique_values, n);

    // Step 5: Print results
    println!("Values that appear exactly once:");
    print_vec(&unique_values);

    println!("\nRandom selection ({} values):", n);
    print_vec(&random_selection);
}


/*
run:

Values that appear exactly once:
12 33 59 61 17 74 83 90 1 

Random selection (5 values):
90 12 61 74 33 

*/

 



answered Sep 13 by avibootz

Related questions

...