Weekly Challenge Answer - Grouped by Frequency

⚓ Rust    📅 2025-11-10    👤 surdeus    👁️ 6      

surdeus

// Rust Bytes Challenge Issue #92 Grouped by Frequency
use std::collections::HashMap;

pub fn group_by_frequency(nums: Vec<i32>) -> Vec<Vec<i32>> {
    let mut frequencies: HashMap<i32, i32> = HashMap::new();
    for i in nums.iter() {
        frequencies.entry(*i).and_modify(|x| *x += 1).or_insert(1);
    }
    let mut sorted_frequencies = frequencies.into_iter().collect::<Vec<_>>();
    sorted_frequencies.sort_by(|a, b| {
        let c = b.1.cmp(&a.1);
        if c == std::cmp::Ordering::Equal {
            a.0.cmp(&b.0)
        } else {
            c
        }
    });
    let mut result: Vec<Vec<i32>> = vec![];
    let mut prev_freq: Option<i32> = None;
    let mut bucket: Vec<i32> = vec![];

    for (elem, freq) in sorted_frequencies.into_iter() {
        if prev_freq == Some(freq) {
            bucket.push(elem);
        } else {
            if !bucket.is_empty() {
                result.push(bucket);
            }
            prev_freq = Some(freq);
            bucket = vec![elem]; // starts a new group of frequencies
        }
    }
    if !bucket.is_empty() {
        result.push(bucket); // the last bucket
    }
    result
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn mixed_frequencies() {
        let input = vec![4, 3, 1, 3, 2, 2, 2, 4, 4];
        let expected = vec![vec![2, 4], vec![3], vec![1]];
        assert_eq!(group_by_frequency(input), expected);
    }

    #[test]
    fn all_unique() {
        let input = vec![5, 4, 3, 2, 1];
        let expected = vec![vec![1, 2, 3, 4, 5]];
        assert_eq!(group_by_frequency(input), expected);
    }

    #[test]
    fn all_identical() {
        let input = vec![7, 7, 7, 7];
        let expected = vec![vec![7]];
        assert_eq!(group_by_frequency(input), expected);
    }

    #[test]
    fn includes_negatives() {
        let input = vec![-1, -1, 2, 2, 3];
        let expected = vec![vec![-1, 2], vec![3]];
        assert_eq!(group_by_frequency(input), expected);
    }

    #[test]
    fn empty_input() {
        let input: Vec<i32> = vec![];
        let expected: Vec<Vec<i32>> = vec![];
        assert_eq!(group_by_frequency(input), expected);
    }
}

(Playground)

Output:


running 5 tests
test tests::all_identical ... ok
test tests::all_unique ... ok
test tests::empty_input ... ok
test tests::includes_negatives ... ok
test tests::mixed_frequencies ... ok

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s


Errors:

   Compiling playground v0.0.1 (/playground)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 1.31s
     Running unittests src/lib.rs (target/debug/deps/playground-bf5271b42b19fd8b)
   Doc-tests playground

2 posts - 2 participants

Read full topic

🏷️ Rust_feed