// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::random_union3s; use crate::extra_variadic::Union3; use core::hash::Hash; use itertools::Itertools; use malachite_base::bools::random::random_bools; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_unsigned_inclusive_range; use malachite_base::orderings::random::random_orderings; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::strings::random::random_strings_using_chars; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::unions::random::random_union2s; use malachite_base::unions::Union2; use std::cmp::Ordering::*; use std::fmt::Debug; fn random_union2s_helper< X: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, Y: Clone + Debug + Eq + Hash + Ord, J: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, expected_values: &[Union2], expected_common_values: &[(Union2, usize)], expected_median: (Union2, Option>), ) { let us = random_union2s(EXAMPLE_SEED, xs_gen, ys_gen); let values = us.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, us.clone()); let median = median(us.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_union2s() { random_union2s_helper( &|seed| random_char_inclusive_range(seed, 'a', 'z'), &|seed| random_unsigned_inclusive_range::(seed, 1, 10), &[ Union2::A('v'), Union2::B(3), Union2::A('c'), Union2::A('q'), Union2::A('i'), Union2::A('e'), Union2::A('p'), Union2::A('g'), Union2::A('s'), Union2::B(7), Union2::A('n'), Union2::A('t'), Union2::B(9), Union2::A('m'), Union2::A('z'), Union2::B(7), Union2::B(9), Union2::A('o'), Union2::A('m'), Union2::B(3), ], &[ (Union2::B(5), 50535), (Union2::B(4), 50190), (Union2::B(10), 50183), (Union2::B(3), 50068), (Union2::B(9), 50064), (Union2::B(6), 50002), (Union2::B(2), 49882), (Union2::B(1), 49807), (Union2::B(7), 49533), (Union2::B(8), 49495), ], (Union2::A('z'), None), ); random_union2s_helper( &random_bools, &|seed| geometric_random_unsigneds::(seed, 4, 1), &[ Union2::A(true), Union2::B(6), Union2::A(false), Union2::A(true), Union2::A(false), Union2::A(true), Union2::A(false), Union2::A(true), Union2::A(false), Union2::B(0), Union2::A(true), Union2::A(true), Union2::B(2), Union2::A(false), Union2::A(true), Union2::B(2), Union2::B(2), Union2::A(false), Union2::A(false), Union2::B(8), ], &[ (Union2::A(false), 250462), (Union2::A(true), 249779), (Union2::B(0), 100190), (Union2::B(1), 79510), (Union2::B(2), 63929), (Union2::B(3), 51260), (Union2::B(4), 41099), (Union2::B(5), 32494), (Union2::B(6), 26037), (Union2::B(7), 21139), ], (Union2::A(true), None), ); } #[allow(clippy::type_complexity)] fn random_union3s_helper< X: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, Y: Clone + Debug + Eq + Hash + Ord, J: Clone + Iterator, Z: Clone + Debug + Eq + Hash + Ord, K: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, zs_gen: &dyn Fn(Seed) -> K, expected_values: &[Union3], expected_common_values: &[(Union3, usize)], expected_median: (Union3, Option>), ) { let us = random_union3s(EXAMPLE_SEED, xs_gen, ys_gen, zs_gen); let values = us.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, us.clone()); let median = median(us.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_union3s() { random_union3s_helper( &|seed| random_char_inclusive_range(seed, 'a', 'z'), &|seed| random_unsigned_inclusive_range::(seed, 1, 10), &random_orderings, &[ Union3::C(Equal), Union3::A('v'), Union3::A('c'), Union3::A('q'), Union3::C(Greater), Union3::A('i'), Union3::B(3), Union3::C(Greater), Union3::B(7), Union3::C(Greater), Union3::C(Greater), Union3::C(Greater), Union3::B(9), Union3::C(Equal), Union3::A('e'), Union3::A('p'), Union3::A('g'), Union3::A('s'), Union3::C(Equal), Union3::A('n'), ], &[ (Union3::C(Less), 111378), (Union3::C(Greater), 111191), (Union3::C(Equal), 110903), (Union3::B(5), 33724), (Union3::B(10), 33503), (Union3::B(4), 33375), (Union3::B(9), 33348), (Union3::B(2), 33347), (Union3::B(6), 33288), (Union3::B(7), 33283), ], (Union3::B(5), None), ); random_union3s_helper( &random_bools, &|seed| geometric_random_unsigneds::(seed, 4, 1), &|seed| { random_strings_using_chars( seed, &|seed_2| random_char_inclusive_range(seed_2, 'a', 'z'), 4, 1, ) }, &[ Union3::C("qvfm".to_string()), Union3::A(true), Union3::A(false), Union3::A(true), Union3::C("kt".to_string()), Union3::A(false), Union3::B(6), Union3::C("auqoox".to_string()), Union3::B(0), Union3::C("ak".to_string()), Union3::C("".to_string()), Union3::C("dz".to_string()), Union3::B(2), Union3::C("ebaq".to_string()), Union3::A(true), Union3::A(false), Union3::A(true), Union3::A(false), Union3::C("gvqmloscuftfzjrn".to_string()), Union3::A(true), ], &[ (Union3::A(false), 166833), (Union3::A(true), 166495), (Union3::B(0), 66610), (Union3::C("".to_string()), 66483), (Union3::B(1), 53004), (Union3::B(2), 42754), (Union3::B(3), 34312), (Union3::B(4), 27360), (Union3::B(5), 21599), (Union3::B(6), 17332), ], (Union3::B(3), None), ); }