// 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 itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::striped::striped_random_unsigned_vecs_from_length_iterator; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::vecs::random_values_from_vec; use std::iter::repeat; fn striped_random_unsigned_vecs_from_length_iterator_helper< T: PrimitiveUnsigned, I: Clone + Iterator, >( lengths_gen: &dyn Fn(Seed) -> I, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&[&str]], expected_common_values: &[(&[&str], usize)], expected_median: (&[&str], Option<&[&str]>), ) { let xss = striped_random_unsigned_vecs_from_length_iterator::( EXAMPLE_SEED, lengths_gen, mean_stripe_numerator, mean_stripe_denominator, ); let values = xss .clone() .take(20) .map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xss.clone()) .into_iter() .map(|(xs, freq)| { ( xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(), freq, ) }) .collect_vec(); let (median_lo, median_hi) = median(xss.take(1000000)); let median_lo = median_lo .into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(); let median_hi = median_hi.map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }); let values = values .iter() .map(|xs| xs.iter().map(String::as_str).collect_vec()) .collect_vec(); let common_values = common_values .iter() .map(|(xs, freq)| (xs.iter().map(String::as_str).collect_vec(), *freq)) .collect_vec(); let median_lo = median_lo.iter().map(String::as_str).collect_vec(); let median_hi = median_hi .as_ref() .map(|xs| xs.iter().map(String::as_str).collect_vec()); assert_eq!( ( values.iter().map(Vec::as_slice).collect_vec().as_slice(), common_values .iter() .map(|(xs, f)| (xs.as_slice(), *f)) .collect_vec() .as_slice(), (median_lo.as_slice(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_unsigned_vecs_from_length_iterator() { striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 2, 1, &[ &["11001100", "11000"], &["110010", "1111010", "1111101", "1100001"], &["1001100", "1111"], &["10110000", "11011", "1111", "101000"], &["11100110", "1111011", "10001101", "111110"], &["100111", "11101011"], &[], &["1100010", "101011"], &[], &["10100111", "100000", "1110011", "11111111"], &["1011010", "100010", "1100100", "1110110"], &["10000111", "11101111"], &["1100011", "11100101", "10001010", "11011011"], &["1001000", "11011101"], &["10100000", "101110", "11101110", "111101"], &["1100010", "1001111", "1100001", "100"], &["100111", "11100010", "110011", "11011110"], &[], &["10100", "11001011", "11100000", "1001101"], &[], ], &[ (&[], 333820), (&["11110010", "1100111"], 17), (&["10010101", "101"], 16), (&["11010100", "1100001"], 16), (&["1111101", "11100000"], 16), (&["11111111", "1111000"], 16), (&["101100", "110101"], 15), (&["1010111", "1010000"], 15), (&["10101", "1111110"], 15), (&["11110111", "10000"], 15), ], ( &["111111", "11110001", "11111010", "10100110"], Some(&["111111", "11110010"]), ), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 10, 1, &[ &["0", "0"], &["1110000", "0", "11111100", "11"], &["11111110", "1111"], &["0", "0", "0", "11111000"], &["0", "0", "1111110", "0"], &["11011111", "11111111"], &[], &["11110000", "11111111"], &[], &["11111111", "11000011", "11111", "0"], &["0", "10000000", "11111001", "1111111"], &["11111111", "11111111"], &["11111111", "11111111", "11111111", "11111111"], &["0", "10000"], &["0", "0", "0", "11111100"], &["0", "0", "0", "0"], &["11111111", "0", "11110001", "11111111"], &[], &["10111100", "11", "10110100", "11101111"], &[], ], &[ (&[], 333820), (&["11111111", "11111111"], 34254), (&["0", "0"], 34215), (&["11111111", "11111111", "11111111", "11111111"], 6413), (&["0", "0", "0", "0"], 6336), (&["11111111", "11111"], 3951), (&["111111", "0"], 3891), (&["11111110", "11111111"], 3890), (&["11111111", "0"], 3889), (&["11111111", "1111"], 3878), ], (&["1", "0", "11111110", "11111111"], None), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 11, 10, &[ &["1011010", "11010101"], &["1101010", "10010101", "1010010", "10101010"], &["10101010", "10101010"], &["11010100", "10101010", "101010", "1101011"], &["10101010", "10101010", "10101010", "1001010"], &["10110101", "1010010"], &[], &["1001010", "1010101"], &[], &["1010101", "10110101", "10101010", "1010110"], &["1010100", "1010101", "1010101", "10010101"], &["1001001", "1010101"], &["1010101", "100101", "1010101", "1010101"], &["10110100", "10101010"], &["10101010", "10101010", "10111100", "11100"], &["10101010", "10001010", "1010110", "10100101"], &["10101011", "1101010", "1010101", "10110101"], &[], &["10101010", "1010100", "10110101", "10101010"], &[], ], &[ (&[], 333820), (&["1010101", "1010101"], 39945), (&["10101010", "10101010"], 39772), (&["1010101", "1010101", "1010101", "1010101"], 8708), (&["10101010", "10101010", "10101010", "10101010"], 8700), (&["1010010", "1010101"], 4100), (&["1010101", "10110101"], 4090), (&["1010101", "11010101"], 4089), (&["1010101", "10101101"], 4080), (&["1010110", "1010101"], 4060), ], (&["1010101", "1010101", "1010101", "10110101"], None), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 2, 1, &[ &[ "11001100", "11000", "11001", "10111101", "10111110", "110000", "11010011", "11", "1110110", "11100011", "1", "1100101", ], &["1111100", "10101111"], &[ "1011100", "11110000", "1100100", "11011101", "1001001", "111101", "101", "10011001", "11111011", "10010111", "1110110", "1101111", "100110", "1110", "11011111", "1100011", ], &["11001010", "10101"], &[ "1101110", "1101111", "1000101", "10100000", "101110", "11101110", "111101", "10110001", "10100111", "110000", "10", "1110110", "111", "1110011", "10001000", "1100010", "11001", "10111100", "10101001", "11001000", "110", "1101", "1100101", "1111011", "11011", "10101101", "11111111", "10011110", ], &[], &[ "11110001", "1100011", "11001000", "1111111", "11001100", "11001101", "11100011", "11011000", "110101", "10000111", ], &[ "11011100", "10111010", "10000101", "0", "10110010", "10010010", "10111000", "10010100", ], &["11010001", "1111000"], &[], &[ "1010100", "10101110", "1000001", "1001011", "1011100", "10110100", "11001000", "1101", "10010101", "10111011", "1111000", "1011", ], &["1010011", "111001", "10101111", "1100101"], &[], &[], &["10010001", "11010001"], &["10111110", "11101111", "11101011", "10010", "1101101", "1010110"], &[], &["100110", "10001010"], &[], &["1101100", "11000"], ], &[ (&[], 333981), (&["1", "10011100"], 13), (&["11111011", "110100"], 13), (&["110000", "10110111"], 13), (&["1100110", "10011000"], 13), (&["11101100", "11011100"], 13), (&["1", "100101"], 12), (&["100010", "101100"], 12), (&["1010", "11000011"], 12), (&["1100101", "1001101"], 12), ], (&["111111", "10101111"], None), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 10, 1, &[ &[ "0", "0", "111000", "0", "11111110", "10000001", "11111111", "11", "0", "0", "0", "11111111", ], &["0", "11000000"], &[ "11100000", "11111111", "11111011", "11111111", "0", "0", "11100000", "1", "11111111", "11111111", "11111111", "11001", "0", "11111110", "11111111", "11111111", ], &["0", "0"], &[ "0", "0", "100000", "0", "0", "0", "11111100", "11111111", "11111111", "11111111", "11111111", "111111", "1000000", "11111100", "1111111", "10001000", "1111111", "1001", "10", "0", "0", "0", "11111111", "11100001", "10111111", "1", "11111000", "1111111", ], &[], &[ "11111111", "11011111", "11111111", "11111111", "11", "11000000", "11111111", "11111111", "11110000", "11111111", ], &["11111110", "0", "0", "11100000", "11111111", "1111", "0", "11111111"], &["11110011", "11111111"], &[], &[ "10001000", "11111111", "11", "11111110", "0", "11111100", "11111111", "11111111", "11111111", "11", "11111111", "11111", ], &["11111111", "1100001", "0", "11100000"], &[], &[], &["11111111", "11111111"], &["11111000", "1111111", "0", "10000000", "111", "1111"], &[], &["0", "0"], &[], &["0", "0"], ], &[ (&[], 333981), (&["0", "0"], 22998), (&["11111111", "11111111"], 22759), (&["11111111", "11111111", "11111111", "11111111"], 2851), (&["0", "0", "0", "0"], 2788), (&["11111111", "111111"], 2626), (&["1111", "0"], 2620), (&["111", "0"], 2615), (&["111111", "0"], 2608), (&["11111000", "11111111"], 2608), ], ( &["1", "0", "11111000", "1", "1111100", "0", "0", "100000"], Some(&["1", "0", "11111000", "1", "10000000", "11111111", "11111111", "11111111"]), ), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 11, 10, &[ &[ "1011010", "11010101", "1001010", "10110101", "11010110", "10101010", "10101010", "1101010", "10100101", "10101010", "10011010", "1010010", ], &["10101010", "10101010"], &[ "10101010", "1010010", "10101001", "1010101", "10101011", "10101010", "10101010", "1010101", "10110101", "1010010", "1010101", "1010101", "1010101", "10010010", "10101010", "10101010", ], &["1001010", "10101010"], &[ "10101010", "10010110", "10101010", "10101010", "10101010", "10111100", "11100", "1010101", "1000101", "10101011", "11010010", "10101010", "1011010", "1010101", "10101101", "1101010", "1010101", "10101001", "10101010", "10101010", "10101010", "10101010", "100101", "10100101", "1010101", "1010101", "1010101", "10010101", ], &[], &[ "1010101", "1010101", "10101101", "1010110", "1101010", "11010101", "10100110", "10101010", "10101010", "11010100", ], &[ "10101010", "10110110", "10101010", "101010", "1010101", "1010101", "10101010", "10101010", ], &["10010101", "10101010"], &[], &[ "10101010", "1001010", "1010101", "1011101", "10010101", "10101010", "10101010", "10101010", "10101010", "10110101", "10010100", "1010101", ], &["1010101", "1010101", "1010101", "1010101"], &[], &[], &["1010101", "1001010"], &["1001010", "10101101", "11010010", "10101010", "1101010", "1010101"], &[], &["10000100", "10101010"], &[], &["10101010", "101010"], ], &[ (&[], 333981), (&["10101010", "10101010"], 26752), (&["1010101", "1010101"], 26461), (&["10101010", "10101010", "10101010", "10101010"], 3857), (&["1010101", "1010101", "1010101", "1010101"], 3852), (&["10101010", "1010010"], 2802), (&["1010110", "1010101"], 2776), (&["1010101", "10100101"], 2768), (&["1010101", "10010101"], 2739), (&["10101011", "10101010"], 2730), ], (&["1010101", "1010101", "10010101", "10101010"], None), ); } #[test] #[should_panic] fn striped_random_unsigned_vecs_from_length_iterator_fail_1() { striped_random_unsigned_vecs_from_length_iterator::(EXAMPLE_SEED, &|_| repeat(1), 1, 0); } #[test] #[should_panic] fn striped_random_unsigned_vecs_from_length_iterator_fail_2() { striped_random_unsigned_vecs_from_length_iterator::(EXAMPLE_SEED, &|_| repeat(1), 2, 3); }