From da4f06a825365550e240c93c18557a1d4619da8d Mon Sep 17 00:00:00 2001 From: hal8174 Date: Mon, 2 Dec 2024 21:07:44 +0100 Subject: [PATCH] Fix bug and minor improvements --- closest_string/Cargo.toml | 3 +++ closest_string/cs0.out | 2 +- closest_string/cs1.out | 2 +- closest_string/cs2.out | 2 +- closest_string/cs3.out | 2 +- closest_string/cs4.out | 2 +- closest_string/src/main.rs | 52 +++++++++++++++++++++++++++++--------- 7 files changed, 48 insertions(+), 17 deletions(-) diff --git a/closest_string/Cargo.toml b/closest_string/Cargo.toml index 17a0c76..dea786b 100644 --- a/closest_string/Cargo.toml +++ b/closest_string/Cargo.toml @@ -3,5 +3,8 @@ name = "closest_string" version = "0.1.0" edition = "2021" +[profile.release] +debug = true + [dependencies] clap = { version = "4.5.21", features = ["derive"] } diff --git a/closest_string/cs0.out b/closest_string/cs0.out index 768138b..06174f7 100644 --- a/closest_string/cs0.out +++ b/closest_string/cs0.out @@ -1 +1 @@ -dbadcabbcbaccbabadbb +dbaccabbcbacccabadbb diff --git a/closest_string/cs1.out b/closest_string/cs1.out index 12f8dc3..ae90d7c 100644 --- a/closest_string/cs1.out +++ b/closest_string/cs1.out @@ -1 +1 @@ -acdccadadcbadcdbdaaadacbcdcacbbdcdabbbbddbcbccdbabccccdbbacccdccccacaaddcabaaabbbadacbbddaccccbcccbb +acdccadbddbadcdbdaaadacbcccacbbdcdabbbbddbcbccdbabccacdbbacccdccccccaaadcabaaabbaadacbbddbacbcbcccbb diff --git a/closest_string/cs2.out b/closest_string/cs2.out index 27c30b2..4ffe3bc 100644 --- a/closest_string/cs2.out +++ b/closest_string/cs2.out @@ -1 +1 @@ -cdbdbdbababcdaacbabbdadccdbdcdaacdbaacccddcdbbacadcbcacddcddacdaddcbbacbbddcccdcdbcbacccbabbcbbbaaaa +cdbdbdbdaabcdaaadabbdadccdbdcdaacdbaaaccddcdbbacadabcacddcddaddadddbbacbaddcccdcdbcbbbccbabbcbbbaaaa diff --git a/closest_string/cs3.out b/closest_string/cs3.out index c6e27de..74f5781 100644 --- a/closest_string/cs3.out +++ b/closest_string/cs3.out @@ -1 +1 @@ -bcdcacdbbbcbbadbbbaabdadcaddcddabbdacddacaaccadcaabdcdddddadacbdcdcbccabbbabdddbacaddcaacaadacbacbdd +bddcacdabbcbbcdcbbaabdadbaddcddacbdadacaddabcbbcaabbcdddadadacbdcdcbaaccbbabcdabaccddcaaddadacbacbdd diff --git a/closest_string/cs4.out b/closest_string/cs4.out index 5f556e7..9811f23 100644 --- a/closest_string/cs4.out +++ b/closest_string/cs4.out @@ -1 +1 @@ -bcdbdcdaabaacdbcddadbddcaabcabaadbbccdcbbdbbbccadcaabcbbcdbbcbbbbccacaabbdcdaccbaaaddccbcdcacdcbcacd +aadbdcdaabcacdbbdbccddcaaadcdbaadbcccdcbbdbbbdcadcadbcbabdbbccbdbccacabbbbcddccaaaadddbbcdcacdcbcacd diff --git a/closest_string/src/main.rs b/closest_string/src/main.rs index 13c4429..7dd2611 100644 --- a/closest_string/src/main.rs +++ b/closest_string/src/main.rs @@ -20,27 +20,52 @@ fn calculate_hamming_distance(a: &[u8], b: &[u8]) -> usize { fn simple<'a>( strings: &[Vec], + hamming_distances: &mut [u8], solution: &'a mut [u8], - d: usize, - depth: usize, + d: u8, + depth: u8, ) -> Option<&'a [u8]> { - let (s, i) = strings + let (s, &i) = strings .iter() - .map(|s| (s, calculate_hamming_distance(s, solution))) - .max_by_key(|(_, i)| *i) + .zip(hamming_distances.iter()) + .max_by_key(|(_, &i)| i) .unwrap(); + // assert_eq!(i, calculate_hamming_distance(s, solution) as u8); + if i > d + depth { return None; } else if i <= d { return Some(solution); } + if depth == 0 { + return None; + } + for index in 0..s.len() { if s[index] != solution[index] { let temp = solution[index]; solution[index] = s[index]; - simple(strings, solution, d, depth + 1)?; + for j in 0..hamming_distances.len() { + if strings[j][index] == temp { + hamming_distances[j] += 1; + } + if strings[j][index] == s[index] { + hamming_distances[j] -= 1; + } + } + if simple(strings, hamming_distances, solution, d, depth - 1).is_some() { + return Some(solution); + } + for j in 0..hamming_distances.len() { + if strings[j][index] == temp { + hamming_distances[j] -= 1; + } + if strings[j][index] == s[index] { + hamming_distances[j] += 1; + } + } solution[index] = temp; } } @@ -48,12 +73,15 @@ fn simple<'a>( None } -fn closest_string(strings: &[Vec], d: usize, method: Method) -> Option> { +fn closest_string(strings: &[Vec], d: u8, method: Method) -> Option> { match method { Method::Simple => { let mut s = strings[0].clone(); - - if simple(strings, &mut s, d, 0).is_some() { + let mut hamming_distances = strings + .iter() + .map(|l| calculate_hamming_distance(&s, l) as u8) + .collect::>(); + if simple(strings, &mut hamming_distances, &mut s, d, d).is_some() { Some(s) } else { None @@ -70,7 +98,7 @@ enum Method { #[derive(Debug, Parser)] struct Args { filename: PathBuf, - d: Option, + d: Option, #[clap(default_value = "simple")] method: Method, #[clap(short, long)] @@ -89,14 +117,14 @@ fn main() { eprintln!("{}: {:?}", d, start.elapsed()); r } else if args.reverse { - let mut d = strings.len(); + let mut d = strings.len() as u8; let mut last_solution = None; loop { let start = std::time::Instant::now(); let r = closest_string(&strings, d, args.method); eprintln!("{}: {:?}", d, start.elapsed()); if let Some(r) = r { - d = r.len() - 1; + d = r.len() as u8 - 1; last_solution = Some(r); } else { break last_solution;