// 1031: Count Frequencies
// The classic frequency counting pattern with Entry API
use std::collections::HashMap;
/// Count character frequencies
fn char_frequency() {
let text = "abracadabra";
let mut counts: HashMap<char, usize> = HashMap::new();
for ch in text.chars() {
*counts.entry(ch).or_insert(0) += 1;
}
assert_eq!(counts[&'a'], 5);
assert_eq!(counts[&'b'], 2);
assert_eq!(counts[&'r'], 2);
assert_eq!(counts[&'c'], 1);
assert_eq!(counts[&'d'], 1);
}
/// Count word frequencies using and_modify
fn word_frequency() {
let words = vec!["the", "cat", "sat", "on", "the", "mat", "the", "cat"];
let mut counts: HashMap<&str, usize> = HashMap::new();
for word in &words {
counts
.entry(word)
.and_modify(|c| *c += 1)
.or_insert(1);
}
assert_eq!(counts["the"], 3);
assert_eq!(counts["cat"], 2);
assert_eq!(counts["sat"], 1);
}
/// Find the most frequent element
fn most_frequent() {
let items = vec![1, 2, 3, 2, 1, 2, 3, 2, 2];
let mut counts: HashMap<i32, usize> = HashMap::new();
for &x in &items {
*counts.entry(x).or_insert(0) += 1;
}
let (most, count) = counts
.iter()
.max_by_key(|&(_, &v)| v)
.map(|(&k, &v)| (k, v))
.unwrap();
assert_eq!(most, 2);
assert_eq!(count, 5);
}
/// Frequency counting with iterators (functional style)
fn functional_counting() {
let data = vec![1, 1, 2, 3, 3, 3];
let counts: HashMap<i32, usize> = data.iter().fold(HashMap::new(), |mut acc, &x| {
*acc.entry(x).or_insert(0) += 1;
acc
});
assert_eq!(counts[&1], 2);
assert_eq!(counts[&3], 3);
}
fn main() {
char_frequency();
word_frequency();
most_frequent();
functional_counting();
println!("โ All tests passed");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_char_frequency() { char_frequency(); }
#[test]
fn test_word_frequency() { word_frequency(); }
#[test]
fn test_most_frequent() { most_frequent(); }
#[test]
fn test_functional_counting() { functional_counting(); }
#[test]
fn test_empty_input() {
let empty: Vec<i32> = vec![];
let counts: HashMap<i32, usize> = empty.iter().fold(HashMap::new(), |mut acc, &x| {
*acc.entry(x).or_insert(0) += 1;
acc
});
assert!(counts.is_empty());
}
}
(* 1031: Count Frequencies *)
(* Count occurrences of each element *)
module CharMap = Map.Make(Char)
module StringMap = Map.Make(String)
(* Approach 1: Character frequency counting *)
let char_frequency () =
let text = "abracadabra" in
let counts = String.fold_left (fun acc ch ->
let n = match CharMap.find_opt ch acc with
| Some n -> n
| None -> 0
in
CharMap.add ch (n + 1) acc
) CharMap.empty text in
assert (CharMap.find 'a' counts = 5);
assert (CharMap.find 'b' counts = 2);
assert (CharMap.find 'r' counts = 2);
assert (CharMap.find 'c' counts = 1);
assert (CharMap.find 'd' counts = 1)
(* Approach 2: Word frequency *)
let word_frequency () =
let words = ["the"; "cat"; "sat"; "on"; "the"; "mat"; "the"; "cat"] in
let counts = List.fold_left (fun acc w ->
let n = match StringMap.find_opt w acc with
| Some n -> n
| None -> 0
in
StringMap.add w (n + 1) acc
) StringMap.empty words in
assert (StringMap.find "the" counts = 3);
assert (StringMap.find "cat" counts = 2);
assert (StringMap.find "sat" counts = 1)
(* Approach 3: Most frequent element *)
let most_frequent () =
let items = [1; 2; 3; 2; 1; 2; 3; 2; 2] in
module IntMap = Map.Make(Int) in
let counts = List.fold_left (fun acc x ->
let n = match IntMap.find_opt x acc with
| Some n -> n
| None -> 0
in
IntMap.add x (n + 1) acc
) IntMap.empty items in
let (most, count) = IntMap.fold (fun k v (mk, mv) ->
if v > mv then (k, v) else (mk, mv)
) counts (0, 0) in
assert (most = 2);
assert (count = 5)
let () =
char_frequency ();
word_frequency ();
most_frequent ();
Printf.printf "โ All tests passed\n"