// 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 malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::logic::traits::{CountOnes, CountZeros}; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_2, signed_gen_var_4, signed_pair_gen, signed_pair_gen_var_1, signed_triple_gen_var_3, unsigned_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] pub fn test_hamming_distance() { fn test(x: T, y: T, out: u64) { assert_eq!(x.hamming_distance(y), out); } test(123u16, 456u16, 6); test(0xffffu32, 0xffff0000u32, 32); test(0xffffu32, u32::MAX, 16); test(0xffff0000u32, u32::MAX, 16); } #[test] pub fn test_checked_hamming_distance() { fn test(x: T, y: T, out: Option) { assert_eq!(x.checked_hamming_distance(y), out); } test(123i32, 456i32, Some(6)); test(-123i32, -456i32, Some(7)); test(0i8, 127i8, Some(7)); test(0i8, -1i8, None); test(-1i8, -128i8, Some(7)); test(0i128, i128::MAX, Some(127)); test(0i128, -1i128, None); test(-1i128, i128::MIN, Some(127)); test(0xffffi32, 0x7fff0000i32, Some(31)); test(0xffffi32, i32::MAX, Some(15)); test(0x7fff0000i32, i32::MAX, Some(16)); } fn hamming_distance_properties_helper() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let distance = x.hamming_distance(y); assert_eq!(y.hamming_distance(x), distance); assert_eq!(distance == 0, x == y); assert_eq!(CountOnes::count_ones(x ^ y), distance); assert_eq!((!x).hamming_distance(!y), distance); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { assert!(x.hamming_distance(z) <= x.hamming_distance(y) + y.hamming_distance(z)); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.hamming_distance(x), 0); assert_eq!(x.hamming_distance(!x), T::WIDTH); assert_eq!(x.hamming_distance(T::ZERO), CountOnes::count_ones(x)); assert_eq!(T::ZERO.hamming_distance(x), CountOnes::count_ones(x)); }); } #[test] fn hamming_distance_properties() { apply_fn_to_unsigneds!(hamming_distance_properties_helper); } fn checked_hamming_distance_properties_helper() { signed_pair_gen::().test_properties(|(x, y)| { let distance = x.checked_hamming_distance(y); assert_eq!(y.checked_hamming_distance(x), distance); assert_eq!(distance == Some(0), x == y); assert_eq!((!x).checked_hamming_distance(!y), distance); }); signed_pair_gen_var_1::().test_properties(|(x, y)| { let distance = x.checked_hamming_distance(y).unwrap(); assert_eq!(y.checked_hamming_distance(x).unwrap(), distance); assert_eq!(distance == 0, x == y); assert_eq!(CountOnes::count_ones(x ^ y), distance); assert_eq!((!x).checked_hamming_distance(!y).unwrap(), distance); }); signed_triple_gen_var_3::().test_properties(|(x, y, z)| { assert!( x.checked_hamming_distance(z).unwrap() <= x.checked_hamming_distance(y).unwrap() + y.checked_hamming_distance(z).unwrap() ); }); signed_gen::().test_properties(|x| { assert_eq!(x.checked_hamming_distance(x), Some(0)); assert_eq!(x.checked_hamming_distance(!x), None); }); signed_gen_var_2::().test_properties(|x| { assert_eq!( x.checked_hamming_distance(T::ZERO), Some(CountOnes::count_ones(x)) ); assert_eq!( T::ZERO.checked_hamming_distance(x), Some(CountOnes::count_ones(x)) ); }); signed_gen_var_4::().test_properties(|x| { assert_eq!( x.checked_hamming_distance(T::NEGATIVE_ONE), Some(CountZeros::count_zeros(x)) ); assert_eq!( T::NEGATIVE_ONE.checked_hamming_distance(x), Some(CountZeros::count_zeros(x)) ); }); } #[test] fn checked_hamming_distance_properties() { apply_fn_to_signeds!(checked_hamming_distance_properties_helper); }