// 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 core::hash::Hash; use itertools::Itertools; use malachite_base::iterators::with_special_values; use malachite_base::num::random::random_primitive_ints; use malachite_base::options::random::random_options; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::fmt::Debug; fn with_special_values_helper( special_values: &[I::Item], p_special_numerator: u64, p_special_denominator: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[I::Item], expected_common_values: &[(I::Item, usize)], expected_median: (I::Item, Option), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = with_special_values( EXAMPLE_SEED, special_values.to_vec(), p_special_numerator, p_special_denominator, xs_gen, ); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_with_special_values() { // special_values = &[0, 1, 2], p = 1/2 with_special_values_helper( &[0, 1, 2], 1, 2, &random_primitive_ints::, &[2, 0, 2, 85, 0, 11, 1, 2, 0, 136, 200, 235, 0, 0, 134, 2, 0, 0, 0, 0], &[ (2, 168816), (0, 168721), (1, 167914), (81, 2080), (208, 2071), (35, 2070), (211, 2051), (112, 2043), (162, 2043), (143, 2041), ], (2, None), ); // special_values = &[0, 1], p = 50/51 with_special_values_helper( &[0, 1], 50, 51, &random_primitive_ints::, &[0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0], &[ (1, 490697), (0, 489910), (18, 101), (25, 99), (116, 97), (226, 97), (237, 97), (23, 95), (185, 95), (30, 94), ], (1, None), ); // p = special_values = &[0, 1, 2, 3], 1/51 with_special_values_helper( &[0, 1, 2, 3], 1, 51, &random_primitive_ints::, &[ 85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32, 166, 234, 30, 218, 90, 106, ], &[ (2, 8933), (0, 8779), (1, 8736), (3, 8736), (58, 4029), (81, 4001), (194, 3979), (66, 3971), (64, 3969), (143, 3965), ], (125, None), ); // special_values = &[None, Some(0), Some(1)], p = 1/11 with_special_values_helper( &[None, Some(0), Some(1)], 1, 11, &|seed| random_options(seed, 1, 11, &random_primitive_ints::), &[ Some(229), Some(58), Some(126), Some(1), Some(192), Some(140), Some(235), Some(50), Some(162), Some(5), Some(14), Some(107), Some(218), None, Some(96), Some(86), Some(51), Some(240), Some(1), Some(186), ], &[ (None, 113578), (Some(1), 33583), (Some(0), 33308), (Some(186), 3381), (Some(193), 3376), (Some(55), 3364), (Some(83), 3364), (Some(245), 3360), (Some(148), 3352), (Some(143), 3345), ], (Some(101), None), ); } #[test] #[should_panic] fn with_special_values_fail_1() { with_special_values(EXAMPLE_SEED, vec![0, 1], 1, 0, &random_primitive_ints::); } #[test] #[should_panic] fn with_special_values_fail_2() { with_special_values(EXAMPLE_SEED, vec![0, 1], 2, 1, &random_primitive_ints::); } #[test] #[should_panic] fn with_special_values_fail_3() { with_special_values(EXAMPLE_SEED, vec![], 1, 2, &random_primitive_ints::); }