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"); assert_eq!( add_binary( "10110101010001101011001011100011\ 10100111101001010011000011000100\ 11110111001001111010110000000010\ 11100100110010110111101001100010\ 10000101100010101010000111100100\ 10100110010010100110111010011001\ 11110111011101010000000110101001\ 10000101110010101101011011011000" .to_string(), "11101111111010110101001000000110\ 10010101100011001110011100101111\ 10011111011100000010100111010100\ 11101111111010111010011111001011\ 00000001001010111100100000010010\ 10110001010101011100001100000010\ 11010000010010011101100000000111\ 10000100111011110110000001110100" .to_string() ), "11010010100110010000001001110101\ 00011110100110010000101111111010\ 01001011010010111110101011101011\ 11101010010110111001000100010110\ 11000011010110110011010011111011\ 10101011110100000001100011001110\ 01100011110111110110110011011000\ 10000101010111010001101110100110\ 0" ); }