// 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 <https://www.gnu.org/licenses/>. use core::hash::Hash; use itertools::Itertools; 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 random_options_helper<I: Clone + Iterator>( p_none_numerator: u64, p_none_denominator: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[Option<I::Item>], expected_common_values: &[(Option<I::Item>, usize)], expected_median: (Option<I::Item>, Option<Option<I::Item>>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_options(EXAMPLE_SEED, p_none_numerator, p_none_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_random_options() { // p = 1/2 random_options_helper( 1, 2, &random_primitive_ints::<u8>, &[ Some(85), Some(11), Some(136), None, Some(200), None, Some(235), Some(134), Some(203), None, None, None, Some(223), Some(38), None, Some(235), Some(217), Some(177), Some(162), Some(32), ], &[ (None, 500454), (Some(81), 2076), (Some(208), 2066), (Some(35), 2065), (Some(211), 2045), (Some(112), 2042), (Some(143), 2039), (Some(162), 2037), (Some(170), 2036), (Some(58), 2035), ], (None, None), ); // p = 50/51 random_options_helper( 50, 51, &random_primitive_ints::<u8>, &[None; 20], &[ (None, 980283), (Some(18), 102), (Some(25), 99), (Some(237), 98), (Some(116), 97), (Some(226), 97), (Some(23), 95), (Some(185), 95), (Some(30), 94), (Some(73), 94), ], (None, None), ); // p = 1/51 random_options_helper( 1, 51, &random_primitive_ints::<u8>, &[ Some(85), Some(11), Some(136), Some(200), Some(235), Some(134), Some(203), Some(223), Some(38), Some(235), Some(217), Some(177), Some(162), Some(32), Some(166), Some(234), Some(30), Some(218), Some(90), Some(106), ], &[ (None, 19543), (Some(58), 4030), (Some(81), 4001), (Some(194), 3981), (Some(66), 3973), (Some(64), 3969), (Some(143), 3965), (Some(4), 3964), (Some(196), 3952), (Some(208), 3941), ], (Some(125), None), ); // p = 1/11 random_options_helper( 1, 11, &|seed| random_options(seed, 1, 11, &random_primitive_ints::<u8>), &[ Some(Some(229)), Some(Some(58)), Some(Some(126)), Some(Some(192)), Some(Some(140)), Some(Some(235)), Some(Some(50)), Some(Some(162)), Some(Some(5)), Some(Some(14)), Some(Some(107)), Some(Some(218)), Some(Some(96)), Some(Some(86)), Some(Some(51)), None, Some(Some(240)), Some(Some(186)), Some(Some(180)), Some(Some(152)), ], &[ (None, 90592), (Some(None), 83007), (Some(Some(186)), 3385), (Some(Some(193)), 3377), (Some(Some(83)), 3366), (Some(Some(55)), 3365), (Some(Some(245)), 3362), (Some(Some(148)), 3354), (Some(Some(143)), 3345), (Some(Some(136)), 3341), ], (Some(Some(101)), None), ); } #[test] #[should_panic] fn random_options_fail_1() { random_options(EXAMPLE_SEED, 1, 0, &random_primitive_ints::<u8>); } #[test] #[should_panic] fn random_options_fail_2() { random_options(EXAMPLE_SEED, 2, 1, &random_primitive_ints::<u8>); }