Skip to main content
added 325 characters in body
Source Link
Davislor
  • 8.3k
  • 17
  • 37

Update: You’ve explained your reasoning in the comments, and it makes sense. Sometimes you want to pad with different elements (zero digits, spaces, null bytes). In that case, I’d still clean up the associated types and traits a bit, but your approach better suits what you wanted and mine is more of a special case.

Update: You’ve explained your reasoning in the comments, and it makes sense. Sometimes you want to pad with different elements (zero digits, spaces, null bytes). In that case, I’d still clean up the associated types and traits a bit, but your approach better suits what you wanted and mine is more of a special case.

added 31 characters in body
Source Link
Davislor
  • 8.3k
  • 17
  • 37

Iterate Over the Bytes of the String, not the CodepointsNow Some Significant Advice

Iterate Over the Bytes of the String, not the Codepoints

Iterate Over the Bytes of the String, not the Codepoints

Now Some Significant Advice

Iterate Over the Bytes of the String, not the Codepoints

added 38 characters in body
Source Link
Davislor
  • 8.3k
  • 17
  • 37
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
        }
    }
}
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 was validated.");

    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
        }
    }
}
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("The output should 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
        }
    }
}
added 45 characters in body
Source Link
Davislor
  • 8.3k
  • 17
  • 37
Loading
Source Link
Davislor
  • 8.3k
  • 17
  • 37
Loading