#![allow(clippy::cast_sign_loss)]
use std::collections::{HashMap, HashSet};
#[must_use]
pub fn all_equal(lst: Vec<u32>) -> bool {
lst.into_iter().collect::<HashSet<u32>>().len() == 1
}
#[must_use]
pub fn all_unique(lst: Vec<u32>) -> bool {
lst.len() == lst.into_iter().collect::<HashSet<u32>>().len()
}
#[must_use]
pub fn bifurcate<'a>(lst: &'a [&str], filter: &'a [bool]) -> Vec<Vec<&'a str>> {
let result1: Vec<&str> = lst
.iter()
.zip(filter)
.filter(|(_, lst2)| **lst2)
.map(|(lst1, _)| *lst1)
.collect();
let result2: Vec<&str> = lst
.iter()
.zip(filter)
.filter(|(_, lst2)| !**lst2)
.map(|(lst1, _)| *lst1)
.collect();
[result1, result2].to_vec()
}
#[must_use]
pub fn bifurcate_by<'a>(lst: &[&'a str], f: &'a dyn Fn(&str) -> bool) -> Vec<Vec<&'a str>> {
let (result, result1): (Vec<&str>, Vec<&str>) = lst.iter().partition(|item| f(item));
[result, result1].to_vec()
}
#[must_use]
pub fn chunk(lst: &[i32], size: usize) -> Vec<Vec<i32>> {
lst.chunks(size).into_iter().map(<[i32]>::to_vec).collect()
}
#[must_use]
pub fn compact(lst: Vec<Option<i32>>) -> Vec<Option<i32>> {
lst.into_iter().filter(<Option<i32>>::is_some).collect()
}
pub fn count_by(lst: Vec<&str>, f: &dyn Fn(&str) -> i32) -> HashMap<i32, i32> {
let mut result = HashMap::new();
for item in lst {
let prev = result.entry(f(item)).or_insert(0);
*prev += 1;
}
result
}
#[must_use]
pub fn count_occurrences(lst: &[i32], val: i32) -> i32 {
lst.iter()
.fold(0, |acc, &x| if x == val { acc + 1 } else { acc })
}
#[must_use]
pub fn deep_flatten(lst: Vec<Vec<i32>>) -> Vec<i32> {
lst.into_iter().flatten().collect()
}
#[must_use]
pub fn difference(a: &[i32], b: &[i32]) -> Vec<i32> {
let b: HashSet<_> = b.iter().copied().collect();
a.iter().filter(|x| !b.contains(x)).copied().collect()
}
pub fn every(lst: &[i32], f: &dyn Fn(i32) -> bool) -> bool {
lst.iter().any(|&x| f(x))
}
#[must_use]
pub fn every_nth(lst: Vec<i32>, nth: usize) -> Vec<i32> {
lst.into_iter().skip(nth - 1).step_by(nth).collect()
}
#[must_use]
pub fn arithmetic_progression(n: i32, lim: i32) -> Vec<i32> {
(n..=lim).step_by(n as usize).collect::<Vec<i32>>()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_all_equal() {
assert!(all_equal(vec![1, 1, 1, 1]));
assert!(!all_equal(vec![1, 2, 3, 4, 5, 6]));
}
#[test]
fn test_all_unique() {
assert!(all_unique(vec![1, 2, 3, 4, 5, 6]));
assert!(!all_unique(vec![1, 2, 2, 3, 4, 5]));
}
#[test]
fn test_bifurcate() {
let expected: Vec<Vec<&str>> = vec![vec!["beep", "boop", "bar"], vec!["foo"]];
assert_eq!(
expected,
bifurcate(
["beep", "boop", "foo", "bar"].as_ref(),
[true, true, false, true].as_ref()
)
);
}
#[test]
fn test_bifurcate_by() {
fn starts_with(item: &str) -> bool {
item.starts_with('b')
}
let expected: Vec<Vec<&str>> = vec![vec!["beep", "boop", "bar"], vec!["foo"]];
assert_eq!(
expected,
bifurcate_by(["beep", "boop", "foo", "bar"].as_ref(), &starts_with)
);
}
#[test]
fn test_chunk() {
let input = vec![1, 2, 3, 4, 5];
let expected = vec![vec![1, 2], vec![3, 4], vec![5]];
assert_eq!(expected, chunk(&input, 2));
let input = vec![1, 2, 3, 4, 5];
let expected = vec![vec![1], vec![2], vec![3], vec![4], vec![5]];
assert_eq!(expected, chunk(&input, 1));
let input = vec![1, 2, 3, 4, 5];
let expected = vec![vec![1, 2, 3, 4, 5]];
assert_eq!(expected, chunk(&input, 5));
}
#[test]
fn test_compact() {
let input = vec![None, Some(1), None, None];
let expected = vec![Some(1)];
assert_eq!(expected, compact(input));
}
#[test]
fn test_count_by() {
fn len(item: &str) -> i32 {
item.len() as i32
}
let expected = HashMap::from([(3, 2), (5, 1)]);
let input = vec!["one", "two", "three"];
assert_eq!(expected, count_by(input, &len));
}
#[test]
fn test_count_occurences() {
let input = vec![1, 1, 2, 1, 2, 3];
assert_eq!(3, count_occurrences(&input, 1));
let input = vec![0, 100, 2, 1, 2, 3];
assert_eq!(1, count_occurrences(&input, 0));
}
#[test]
fn test_deep_flatten() {
let input = vec![vec![1], vec![2], vec![3, 4], vec![5]];
let expected = vec![1, 2, 3, 4, 5];
assert_eq!(expected, deep_flatten(input));
let input = vec![vec![1, 2, 3, 4], vec![5, 6]];
let expected = vec![1, 2, 3, 4, 5, 6];
assert_eq!(expected, deep_flatten(input));
}
#[test]
fn test_difference() {
let (a, b) = (&[1, 2, 3], &[1, 2, 4]);
assert_eq!(vec![3], difference(a, b));
}
#[test]
fn test_every() {
fn bigger(item: i32) -> bool {
item > 1
}
let input = &[4, 2, 3];
assert_eq!(true, every(input, &bigger));
}
#[test]
fn test_every_nth() {
let input = vec![1, 2, 3, 4, 5, 6];
let expected = vec![2, 4, 6];
assert_eq!(expected, every_nth(input, 2));
}
#[test]
fn test_arithmetic_progression() {
assert_eq!(vec![5, 10, 15, 20, 25], arithmetic_progression(5, 25));
assert_eq!(vec![2, 4, 6, 8, 10], arithmetic_progression(2, 10));
}
}