Skip to content

Instantly share code, notes, and snippets.

@AnthonyMikh
Created July 19, 2020 12:00
Show Gist options
  • Save AnthonyMikh/970f042a328ad5f7c02e7d7c20fdd203 to your computer and use it in GitHub Desktop.
Save AnthonyMikh/970f042a328ad5f7c02e7d7c20fdd203 to your computer and use it in GitHub Desktop.
Solution for "Add binary" Leetcode problem
impl Solution {
pub fn add_binary(a: String, b: String) -> String {
enum These {
Both(u8, u8),
Single(u8),
}
use These::*;
let len = a.len().max(b.len()) + 1;
let mut a = a.as_bytes().iter().rev().copied();
let mut b = b.as_bytes().iter().rev().copied();
let digits = std::iter::from_fn(move || {
match (a.next(), b.next()) {
(Some(a), Some(b)) => Some(Both(a, b)),
(Some(d), None) | (None, Some(d)) => Some(Single(d)),
(None, None) => None,
}
});
let (mut ret, carry) = digits.fold((Vec::with_capacity(len), false), |(mut acc, carry), digit| {
let (digit, carry) = match digit {
Both(a, b) => sum_binary(a, b, carry),
Single(d) => sum_binary_with_carry(d, carry),
};
acc.push(digit);
(acc, carry)
});
if carry {
ret.push(b'1');
}
ret.reverse();
String::from_utf8(ret).unwrap()
}
}
fn sum_binary_with_carry(digit: u8, carry: bool) -> (u8, bool) {
match (digit, carry) {
(b'0', false) => (b'0', false),
(_, false) | (b'0', true) => (b'1', false),
(_, true) => (b'0', true),
}
}
fn sum_binary(a: u8, b: u8, carry: bool) -> (u8, bool) {
let sum = (a == b'1') as u8 + (b == b'1') as u8 + carry as u8;
match sum {
0 => (b'0', false),
1 => (b'1', false),
2 => (b'0', true),
_ => (b'1', true),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment