// 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::chars::random::{random_ascii_chars, random_char_inclusive_range};
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 std::iter::repeat;
fn random_strings_using_chars_helper>(
cs_gen: &dyn Fn(Seed) -> I,
mean_length_numerator: u64,
mean_length_denominator: u64,
expected_values: &[&str],
expected_common_values: &[(&str, usize)],
expected_median: (&str, Option<&str>),
) {
let ss = random_strings_using_chars(
EXAMPLE_SEED,
cs_gen,
mean_length_numerator,
mean_length_denominator,
);
let values = ss.clone().take(20).collect_vec();
let common_values = common_values_map_debug(1000000, 10, ss.clone());
let (median_lo, median_hi) = median(ss.take(1000000));
assert_eq!(
(
values.iter().map(String::as_str).collect_vec().as_slice(),
common_values
.iter()
.map(|(s, f)| (s.as_str(), *f))
.collect_vec()
.as_slice(),
(median_lo.as_str(), median_hi.as_deref())
),
(expected_values, expected_common_values, expected_median)
);
}
#[test]
fn test_random_strings_using_chars() {
random_strings_using_chars_helper(
&|_| repeat('a'),
4,
1,
&[
"",
"aaaaaaaaaaaaaa",
"aaaa",
"aaaa",
"a",
"",
"aaaaa",
"aa",
"aaaa",
"",
"aaaaaa",
"",
"",
"aaaaaaaaaaa",
"aaaaaaaa",
"",
"aaa",
"",
"aaaaa",
"aaaaaaaaa",
],
&[
("", 199913),
("a", 160173),
("aa", 128173),
("aaa", 102460),
("aaaa", 81463),
("aaaaa", 65695),
("aaaaaa", 52495),
("aaaaaaa", 41943),
("aaaaaaaa", 33396),
("aaaaaaaaa", 27035),
],
("aaa", None),
);
random_strings_using_chars_helper(
&|seed| random_char_inclusive_range(seed, 'a', 'c'),
4,
1,
&[
"",
"bbbbcaaacacaca",
"cccb",
"acca",
"b",
"",
"cbcac",
"cb",
"cbba",
"",
"ccacca",
"",
"",
"acacbcccccc",
"baccbccb",
"",
"bcc",
"",
"cbbca",
"aacbaabbc",
],
&[
("", 199913),
("c", 53448),
("a", 53374),
("b", 53351),
("ab", 14396),
("aa", 14370),
("cb", 14345),
("cc", 14252),
("ba", 14240),
("ac", 14237),
],
("b", None),
);
random_strings_using_chars_helper(
&random_ascii_chars,
4,
1,
&[
"",
"U\u{16} D<]ae_M,O\u{1d}V",
"(\u{10}&U",
"{P-K",
"Z",
"",
"\u{4}X\u{19}_,",
"\u{1d},",
"?\'[N",
"",
"|}*\u{15}zt",
"",
"",
"\u{2}FXHmX\\\u{8} ZJ",
"\u{b}\u{14}OwV\u{19} R",
"",
"|4\u{e}",
"",
"M$E\u{12}n",
"J)\u{16}\u{1c}\u{11}_T\u{1d}-",
],
&[
("", 199913),
("\u{c}", 1334),
("~", 1322),
("R", 1318),
("o", 1312),
("=", 1310),
("\u{1d}", 1310),
("}", 1308),
("\u{10}", 1306),
("\u{1e}", 1306),
],
("/x\u{b}", Some("/x\u{f}")),
);
random_strings_using_chars_helper(
&random_ascii_chars,
1,
4,
&[
"", "", "U", "\u{16}", " D", "", "", "", "", "", "", "", "<]", "a", "", "e_", "", "",
"", "",
],
&[
("", 800023),
("<", 1334),
("$", 1329),
("\u{b}", 1319),
("%", 1313),
("v", 1309),
("A", 1308),
("\u{1a}", 1308),
("d", 1307),
("B", 1306),
],
("", None),
);
}
#[test]
#[should_panic]
fn random_strings_using_chars_fail_1() {
random_strings_using_chars(EXAMPLE_SEED, &random_ascii_chars, 0, 1);
}
#[test]
#[should_panic]
fn random_strings_using_chars_fail_2() {
random_strings_using_chars(EXAMPLE_SEED, &random_ascii_chars, 1, 0);
}
#[test]
#[should_panic]
fn random_strings_using_chars_fail_3() {
random_strings_using_chars(EXAMPLE_SEED, &random_ascii_chars, u64::MAX, u64::MAX - 1);
}