// 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_triples, random_triples_from_single}; use core::hash::Hash; use itertools::Itertools; use malachite_base::bools::random::random_bools; use malachite_base::chars::random::random_ascii_chars; use malachite_base::num::random::geometric::geometric_random_signeds; use malachite_base::num::random::random_primitive_ints; 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 malachite_base::tuples::random::{random_pairs, random_pairs_from_single}; use malachite_base::tuples::singletons; use std::fmt::Debug; fn random_pairs_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: &[(X, Y)], expected_common_values: &[((X, Y), usize)], expected_median: ((X, Y), Option<(X, Y)>), ) { let xs = random_pairs(EXAMPLE_SEED, xs_gen, ys_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_pairs() { random_pairs_helper( &random_primitive_ints::, &random_bools, &[ (85, false), (11, true), (136, false), (200, false), (235, false), (134, true), (203, true), (223, false), (38, false), (235, false), (217, false), (177, true), (162, false), (32, true), (166, false), (234, true), (30, false), (218, true), (90, true), (106, false), ], &[ ((81, true), 2077), ((58, false), 2074), ((220, false), 2064), ((14, false), 2053), ((194, true), 2050), ((66, false), 2050), ((71, true), 2049), ((208, false), 2043), ((7, true), 2041), ((64, true), 2038), ], ((127, true), None), ); random_pairs_helper( &|seed| random_pairs_from_single(random_primitive_ints::(seed)), &|seed| random_triples_from_single(random_primitive_ints::(seed)), &[ ((85, 11), (98, -88, -58)), ((136, 200), (40, 20, -4)), ((235, 134), (47, 87, -124)), ((203, 223), (72, 77, 63)), ((38, 235), (91, 108, 127)), ((217, 177), (53, -115, 84)), ((162, 32), (18, 10, 112)), ((166, 234), (-102, 104, 53)), ((30, 218), (75, -18, -107)), ((90, 106), (-66, 51, -109)), ((9, 216), (100, 114, -116)), ((204, 151), (2, 63, -67)), ((213, 97), (-34, 67, 119)), ((253, 78), (0, -33, 5)), ((91, 39), (-20, -24, 50)), ((191, 175), (44, -15, 21)), ((170, 232), (22, 94, 27)), ((233, 2), (-128, -36, 25)), ((35, 22), (-5, -13, 50)), ((217, 198), (-119, -21, 46)), ], &[ (((0, 5), (6, 7, 42)), 1), (((8, 8), (18, 5, 6)), 1), (((9, 1), (5, 3, 23)), 1), (((0, 0), (97, 7, 73)), 1), (((0, 2), (12, 20, 6)), 1), (((0, 99), (20, 8, 6)), 1), (((1, 81), (3, 21, 3)), 1), (((1, 83), (-6, 8, 8)), 1), (((1, 9), (-37, 9, 7)), 1), (((1, 9), (4, 95, 15)), 1), ], ( ((127, 197), (-18, 55, -20)), Some(((127, 197), (-8, -68, 49))), ), ); } #[allow(clippy::type_complexity)] fn random_triples_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: &[(X, Y, Z)], expected_common_values: &[((X, Y, Z), usize)], expected_median: ((X, Y, Z), Option<(X, Y, Z)>), ) { let xs = random_triples(EXAMPLE_SEED, xs_gen, ys_gen, zs_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_triples() { random_triples_helper( &random_primitive_ints::, &random_ascii_chars, &|seed| geometric_random_signeds::(seed, 10, 1), &[ (85, 'b', 0), (11, 'P', -6), (136, '\u{1a}', -6), (200, 'F', 8), (235, 'B', 0), (134, '\u{2}', -3), (203, '\u{7f}', -17), (223, '\u{17}', 2), (38, 'W', 0), (235, '\u{8}', 2), (217, '\"', 9), (177, 'j', -6), (162, 't', 20), (32, 'g', -20), (166, '\u{16}', 43), (234, '6', 9), (30, '\u{7f}', -7), (218, 'j', -16), (90, '4', -29), (106, '$', -2), ], &[ ((54, '*', -1), 9), ((252, '\u{c}', 0), 9), ((253, '\u{6}', 0), 9), ((4, '~', 0), 8), ((51, '1', 1), 8), ((131, '!', 1), 8), ((138, 'i', 1), 8), ((185, 'q', 1), 8), ((58, '?', -2), 8), ((225, 'k', -4), 8), ], ((127, 'x', -2), None), ); random_triples_helper( &|seed| singletons(random_bools(seed)), &|seed| random_pairs_from_single(random_primitive_ints::(seed)), &|seed| random_triples_from_single(random_ascii_chars(seed)), &[ ((true,), (98, 168), ('(', '\u{15}', 'h')), ((false,), (198, 40), ('\u{7f}', '%', '\u{7f}')), ((true,), (20, 252), ('\u{13}', '\u{2}', '+')), ((false,), (47, 87), ('\u{1b}', 'v', '\r')), ((true,), (132, 72), ('\u{1b}', '\u{15}', 'I')), ((false,), (77, 63), ('$', '\u{1a}', '}')), ((true,), (91, 108), ('(', '\u{e}', '1')), ((false,), (127, 53), ('$', '/', 'O')), ((true,), (141, 84), ('\u{1f}', 'Z', '>')), ((true,), (18, 10), ('}', '\u{13}', '\\')), ((false,), (112, 154), ('\u{1a}', '\u{14}', 't')), ((true,), (104, 53), (' ', '`', '\u{2}')), ((false,), (75, 238), ('\u{17}', 'a', '8')), ((false,), (149, 190), ('H', ']', '*')), ((false,), (51, 147), ('i', '2', '}')), ((false,), (100, 114), ('\u{3}', '\u{f}', '\u{7f}')), ((false,), (140, 2), ('\u{f}', 'Y', 'D')), ((false,), (63, 189), ('m', '\\', '8')), ((false,), (222, 67), ('M', '\u{7}', '8')), ((true,), (119, 0), ('\u{13}', '.', '\"')), ], &[ (((true,), (57, 9), ('R', '}', 'Q')), 2), (((true,), (233, 229), ('t', '\u{b}', 'Q')), 2), (((false,), (236, 203), ('b', '\u{e}', '\u{e}')), 2), (((true,), (0, 0), ('{', '{', '4')), 1), (((true,), (0, 2), ('-', 'S', '{')), 1), (((true,), (0, 2), ('N', 'E', '-')), 1), (((true,), (0, 2), ('O', '3', 'S')), 1), (((true,), (0, 3), ('"', '/', 'P')), 1), (((true,), (0, 3), (';', 'M', 'W')), 1), (((true,), (0, 3), ('i', ']', 'P')), 1), ], ( ((false,), (255, 175), ('g', '\u{1e}', '4')), Some(((false,), (255, 176), ('\u{10}', 's', '\''))), ), ); }