diff --git a/src/hamming.rs b/src/hamming.rs new file mode 100644 index 0000000..04d77b7 --- /dev/null +++ b/src/hamming.rs @@ -0,0 +1,19 @@ +/// Return the Hamming distance between the strings, +/// or None if the lengths are mismatched. +pub fn hamming_distance(s1: &str, s2: &str) -> Option { + if s1.len() != s2.len() { + return None; + } + + if s1.is_empty() || s2 == s1 { + return Some(0); + } + + let mut count = 0; + for (key, ch) in s1.chars().enumerate() { + if s2.as_bytes()[key] != ch as u8 { + count += 1; + } + } + Some(count) +} diff --git a/src/lib.rs b/src/lib.rs index 5617c52..f997ddc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,7 @@ pub mod fizzy; pub mod sublist; pub mod anagram; pub mod acronym; +pub mod hamming; pub mod luhn_from; pub mod allergies; pub mod luhn_trait; diff --git a/tests/hamming/mod.rs b/tests/hamming/mod.rs new file mode 100644 index 0000000..5dd5241 --- /dev/null +++ b/tests/hamming/mod.rs @@ -0,0 +1,78 @@ +use exercism::hamming; + +fn process_distance_case(strand_pair: [&str; 2], expected_distance: Option) { + assert_eq!( + hamming::hamming_distance(strand_pair[0], strand_pair[1]), + expected_distance + ); +} +#[test] +fn empty_strands() { + process_distance_case(["", ""], Some(0)); +} +#[test] +#[ignore] +/// disallow first strand longer +fn disallow_first_strand_longer() { + process_distance_case(["AATG", "AAA"], None); +} +#[test] +#[ignore] +/// disallow second strand longer +fn disallow_second_strand_longer() { + process_distance_case(["ATA", "AGTG"], None); +} +#[test] +#[ignore] +fn first_string_is_longer() { + process_distance_case(["AAA", "AA"], None); +} +#[test] +#[ignore] +fn second_string_is_longer() { + process_distance_case(["A", "AA"], None); +} +#[test] +#[ignore] +/// single letter identical strands +fn single_letter_identical_strands() { + process_distance_case(["A", "A"], Some(0)); +} +#[test] +#[ignore] +/// small distance +fn single_letter_different_strands() { + process_distance_case(["G", "T"], Some(1)); +} +#[test] +#[ignore] +/// long identical strands +fn long_identical_strands() { + process_distance_case(["GGACTGAAATCTG", "GGACTGAAATCTG"], Some(0)); +} +#[test] +#[ignore] +fn no_difference_between_identical_strands() { + process_distance_case(["GGACTGA", "GGACTGA"], Some(0)); +} +#[test] +#[ignore] +fn complete_hamming_distance_in_small_strand() { + process_distance_case(["ACT", "GGA"], Some(3)); +} +#[test] +#[ignore] +fn small_hamming_distance_in_the_middle_somewhere() { + process_distance_case(["GGACG", "GGTCG"], Some(1)); +} +#[test] +#[ignore] +fn larger_distance() { + process_distance_case(["ACCAGGG", "ACTATGG"], Some(2)); +} +#[test] +#[ignore] +/// large distance in off-by-one strand +fn long_different_strands() { + process_distance_case(["GGACGGATTCTG", "AGGACGGATTCT"], Some(9)); +} diff --git a/tests/libtest.rs b/tests/libtest.rs index 9024343..8214e6a 100644 --- a/tests/libtest.rs +++ b/tests/libtest.rs @@ -38,3 +38,4 @@ mod binary_search; mod spiral_matrix; mod allergies; mod nucleotide_count; +mod hamming;