From 8e8166faaa7dea766524a71ca6a561ba06576273 Mon Sep 17 00:00:00 2001 From: Bauke Date: Fri, 8 Apr 2022 00:06:19 +0200 Subject: [PATCH] Solve add-binary. --- source/add_binary/mod.rs | 68 ++++++++++++++++++++++++++++++++++++++++ source/lib.rs | 1 + 2 files changed, 69 insertions(+) create mode 100644 source/add_binary/mod.rs diff --git a/source/add_binary/mod.rs b/source/add_binary/mod.rs new file mode 100644 index 0000000..5d713c7 --- /dev/null +++ b/source/add_binary/mod.rs @@ -0,0 +1,68 @@ +pub fn add_binary(a: String, b: String) -> String { + // Pad the strings with leading zeroes so they're the same length. + let (a, b) = ( + format!("{:0>1$}", a, b.len()), + format!("{:0>1$}", b, a.len()), + ); + + let mut carry = false; + let mut sum = String::new(); + + // Create reversed iterators for both binary strings. + let (mut a, mut b) = (a.chars().rev(), b.chars().rev()); + + while let Some(a) = a.next() { + // Safe to unwrap since we know both iterators will be the same length. + let b = b.next().unwrap(); + + match (a, b) { + ('1', '1') => { + // For 1 + 1, if we need to carry it will be 01 + 01 -> 10 + 01 -> 11. + // And otherwise it will be 01 + 01 -> 10, and carry next digit. + if carry { + sum.push('1'); + } else { + sum.push('0'); + carry = true; + } + } + + // For 1 + 0 (and associatively 0 + 1), if we need to carry it's the same + // as 01 + 01 -> 10. And keep the carry set. + // And otherwise it will just be 01 + 00 -> 01. + ('1', '0') | ('0', '1') => { + if carry { + sum.push('0'); + } else { + sum.push('1'); + } + } + + // For 0 + 0, if we need to carry it results in 1 and otherwise 0. + ('0', '0') => { + if carry { + sum.push('1'); + carry = false; + } else { + sum.push('0'); + } + } + + _ => unreachable!(), + } + } + + // And if the final digits required carrying, add the 1 here at the end. + if carry { + sum.push('1'); + } + + sum.chars().rev().collect() +} + +#[test] +fn test_add_binary() { + assert_eq!(add_binary("11".to_string(), "1".to_string()), "100"); + assert_eq!(add_binary("1010".to_string(), "1011".to_string()), "10101"); + assert_eq!(add_binary("1111".to_string(), "1111".to_string()), "11110"); +} diff --git a/source/lib.rs b/source/lib.rs index 8194462..51f671a 100644 --- a/source/lib.rs +++ b/source/lib.rs @@ -1,3 +1,4 @@ +pub mod add_binary; pub mod implement_strstr; pub mod length_of_last_word; pub mod longest_common_prefix;