fn zip_pad<IterA, IterB>(mut left_it: IterA, mut right_it: IterB) ->
impl Iterator<Item = (IterA::Item, IterB::Item)>
where
IterA: Iterator,
IterB: Iterator,
IterA::Item: Default,
IterB::Item: Default
{
return std::iter::from_fn(move || {
match (left_it.next(), right_it.next()) {
(None, None) => None,
(Some(left), None) => Some ((left, IterB::Item::default())),
(None, Some(right)) => Some((IterA::Item::default(), right)),
(Some(left), Some(right)) => Some((left, right))
}
})
}
fn ripple_carry_adder( left_input :&str, right_input: &str ) -> String {
let a_rev = left_input.bytes()
.rev()
.map(to_bool);
let b_rev = right_input.bytes()
.rev()
.map(to_bool);
let mut reverse_zip = zip_pad(a_rev, b_rev).peekable();
let mut carry = false;
let mut sum : Vec<u8> = std::iter::from_fn(move|| {
match (reverse_zip.peek(), carry) {
(None, false) => None,
(None, true) => {
carry = false;
Some(true)
}
(Some(&(a, b)), carry_in) => {
let (digit, carry_out) = add_bits(a, b, carry_in);
carry = carry_out;
reverse_zip.next();
Some(digit)
}
}
}).map(to_utf8)
.collect();
/* The output string was generated in reverse order. Reverse it in place,
* without copying.
*/
sum.reverse();
/* Since the bytes of the vector are valid UTF-8, move them to a string,
* without copying.
*/
return String::from_utf8(sum).expect("Input"The wasoutput validatedshould have contained only two possible values.");
const fn to_bool(c :u8) -> bool {
match c as char {
'0' => false,
'1' => true,
_ => unimplemented!()
}
}
const fn add_bits(a: bool, b: bool, c: bool) -> (bool, bool)
{
match (a, b, c) {
(false, false, false) => (false, false),
(false, false, true) => (true, false),
(false, true, false) => (true, false),
(false, true, true) => (false, true),
(true, false, false) => (true, false),
(true, false, true) => (false, true),
(true, true, false) => (false, true),
(true, true, true) => (true, true)
}
}
const fn to_utf8(d: bool) -> u8 {
match d {
false => '0' as u8,
true => '1' as u8
}
}
}