Skip to content
Snippets Groups Projects
Select Git revision
  • 48928b9e753a1cda7b533b1fad063d0ad916250f
  • live_exam_os_ubuntu default protected
2 results

vmDelAccess.go

Blame
  • custom_int.rs 3.37 KiB
    use crate::minimum::Minimum;
    
    /// Larger ints based on a [Vec] of [u8] to repensent arbitrary lengthy numbers.
    /// The number has a sign as well.
    pub struct CustomInt {
        /// The data contains the unsigned integers that are read from right to left
        /// The number 1337 is stored as vec![7, 3, 3, 1]. Each number must be in the range [0,9]
        /// and no trailing 0s are allowed.
        data: Vec<u8>,
        /// Contains the sign of the number +/-1;
        sign: i8,
    }
    
    impl CustomInt {
        /// Tries to create a new [CustomInt]. If the number is valid it returns
        /// an Ok(CustomInt) an Error otherwise.
        ///
        /// # Examples
        ///
        /// ```
        /// use part08::custom_int::CustomInt;
        /// let num = CustomInt::try_new(vec![1, 2, 3, 4], 1);
        /// assert!(num.is_ok());
        /// let num = CustomInt::try_new(vec![1, 2, 3, 4], -1);
        /// assert!(num.is_ok());
        /// let num = CustomInt::try_new(vec![1, 2, 3, 4], 10);
        /// assert!(num.is_err());
        /// let num = CustomInt::try_new(vec![1, 2, 3, 4], -10);
        /// assert!(num.is_err());
        /// ```
        ///
        pub fn try_new(data: Vec<u8>, sign: i8) -> Result<Self, String> {
            // EXERCISE:
            // We don't check for trailing 0s but maybe this could be an exercise.
            // Also we should check numbers are between 0 and 9.
            if sign == 1 || sign == -1 {
                Ok(CustomInt { data, sign })
            } else {
                Err(String::from("Invalid sign."))
            }
        }
    }
    
    impl Clone for CustomInt {
        fn clone(&self) -> Self {
            CustomInt {
                data: self.data.clone(),
                sign: self.sign,
            }
        }
    }
    
    impl Minimum for CustomInt {
        // EXERCISE: Correct this function by using clippy and let it guide you.
        //           Get inspiration from Display to compute the Minimum
        fn min(self, rhs: Self) -> Self {
            if self.sign < rhs.sign {
                return self;
            } else if self.sign > rhs.sign {
                return rhs;
            }
            if self.data.len() < rhs.data.len() {
                return self;
            } else if self.data.len() > rhs.data.len() {
                return rhs;
            }
            for (l, r) in self.data.iter().rev().zip(rhs.data.iter().rev()) {
                let ls = (*l as i8) * self.sign;
                let rs = (*r as i8) * self.sign;
                if ls < rs {
                    return self;
                } else if ls > rs {
                    return rhs;
                }
            }
            self
        }
    }
    
    impl PartialEq for CustomInt {
        fn eq(&self, other: &Self) -> bool {
            if self.sign == other.sign && self.data.len() == other.data.len() {
                self.data
                    .iter()
                    .zip(other.data.iter())
                    .try_fold(true, |_, (l, r)| if l == r { Some(true) } else { None })
                    .is_some()
            } else {
                false
            }
        }
    }
    
    impl std::fmt::Display for CustomInt {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            // This could be replaced by an `?`
            if self.sign == -1 {
                if let Err(e) = write!(f, "-") {
                    return Err(e);
                }
            }
    
            // This could be replaced by an `?`
            let res = self
                .data
                .iter()
                .rev()
                .try_fold((), |_, t| write!(f, "{}", t));
            res
        }
    }
    
    // EXERCISE: write tests
    // EXERCISE: Modify Minimum trait to take references?
    
    #[cfg(test)]
    mod tests {}