]> git.ralfj.de Git - rust-101.git/blobdiff - solutions/src/vec.rs
tuning, exercises and solutions
[rust-101.git] / solutions / src / vec.rs
diff --git a/solutions/src/vec.rs b/solutions/src/vec.rs
new file mode 100644 (file)
index 0000000..8eff916
--- /dev/null
@@ -0,0 +1,127 @@
+pub mod part01 {
+    use std;
+
+    /// A number, or nothing
+    pub enum NumberOrNothing {
+        Number(i32),
+        Nothing
+    }
+    use self::NumberOrNothing::{Number,Nothing};
+
+    /// Compute the minimum element of the vector
+    pub fn vec_min(v: Vec<i32>) -> NumberOrNothing {
+        let mut min = Nothing;
+        for e in v {
+            min = Number(match min {
+                Nothing => e,
+                Number(n) => std::cmp::min(n, e)
+            });
+        }
+        min
+    }
+
+    /// Compute the sum of elements in the vector
+    pub fn vec_sum(v: Vec<i32>) -> i32 {
+        let mut sum = 0;
+        for e in v {
+            sum += e;
+        }
+        sum
+    }
+
+    /// Print all elements in the vector
+    pub fn vec_print(v: Vec<i32>) {
+        for e in v {
+            println!("{}", e)
+        }
+    }
+}
+
+pub mod part0203 {
+    // A polymorphic (generic) "some value, or no value"
+    pub enum SomethingOrNothing<T>  {
+        Something(T),
+        Nothing,
+    }
+    pub use self::SomethingOrNothing::*;
+    type NumberOrNothing = SomethingOrNothing<i32>;
+
+    /// This trait is used to compute the minimum of two elements of the given type
+    pub trait Minimum : Copy {
+        fn min(self, b: Self) -> Self;
+    }
+
+    /// Return the minimum element of the vector
+    pub fn vec_min<T: Minimum>(v: Vec<T>) -> SomethingOrNothing<T> {
+        let mut min = Nothing;
+        for e in v {
+            min = Something(match min {
+                Nothing => e,
+                Something(n) => e.min(n)
+            });
+        }
+        min
+    }
+
+    /// We can compute the minimum of two integers
+    impl Minimum for i32 {
+        fn min(self, b: Self) -> Self {
+            if self < b { self } else { b }
+        }
+    }
+
+    /// Sample program to call vec_min
+    impl NumberOrNothing {
+        pub fn print(self) {
+            match self {
+                Nothing => println!("The number is: <nothing>"),
+                Something(n) => println!("The number is: {}", n),
+            };
+        }
+    }
+    fn read_vec() -> Vec<i32> {
+        vec![18,5,7,3,9,27]
+    }
+    pub fn main_i32() {
+        let vec = read_vec();
+        let min = vec_min(vec);
+        min.print();
+    }
+
+    // Now, all the same for calling it on f32
+    impl Minimum for f32 {
+        fn min(self, b: Self) -> Self {
+            if self < b { self } else { b }
+        }
+    }
+
+    impl SomethingOrNothing<f32> {
+        pub fn print_f32(self) {
+            match self {
+                Nothing => println!("The number is: <nothing>"),
+                Something(n) => println!("The number is: {}", n),
+            };
+        }
+    }
+
+    fn read_vec_f32() -> Vec<f32> {
+        vec![18.01,5.2,7.1,3.,9.2,27.123]
+    }
+    pub fn main_f32() {
+        let vec = read_vec_f32();
+        let min = vec_min(vec);
+        min.print_f32();
+    }
+
+    /// Add a `Display` implementation to `SomethingOrNothing`
+    use std::fmt;
+    impl<T: fmt::Display> fmt::Display for SomethingOrNothing<T> {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            match *self {
+                Something(ref t) => t.fmt(f),
+                Nothing          => "Nothing".fmt(f),
+            }
+        }
+    }
+}
+