Add exercise 10.2 (#24)
[rust-101.git] / solutions / src / vec.rs
1 pub mod part01 {
2     use std;
3
4     /// A number, or nothing
5     pub enum NumberOrNothing {
6         Number(i32),
7         Nothing
8     }
9     use self::NumberOrNothing::{Number,Nothing};
10
11     /// Compute the minimum element of the vector
12     pub fn vec_min(v: Vec<i32>) -> NumberOrNothing {
13         let mut min = Nothing;
14         for e in v {
15             min = Number(match min {
16                 Nothing => e,
17                 Number(n) => std::cmp::min(n, e)
18             });
19         }
20         min
21     }
22
23     /// Compute the sum of elements in the vector
24     pub fn vec_sum(v: Vec<i32>) -> i32 {
25         let mut sum = 0;
26         for e in v {
27             sum += e;
28         }
29         sum
30     }
31
32     /// Print all elements in the vector
33     pub fn vec_print(v: Vec<i32>) {
34         for e in v {
35             println!("{}", e)
36         }
37     }
38 }
39
40 pub mod part0203 {
41     // A polymorphic (generic) "some value, or no value"
42     pub enum SomethingOrNothing<T>  {
43         Something(T),
44         Nothing,
45     }
46     pub use self::SomethingOrNothing::*;
47     type NumberOrNothing = SomethingOrNothing<i32>;
48
49     /// This trait is used to compute the minimum of two elements of the given type
50     pub trait Minimum : Copy {
51         fn min(self, b: Self) -> Self;
52     }
53
54     /// Return the minimum element of the vector
55     pub fn vec_min<T: Minimum>(v: Vec<T>) -> SomethingOrNothing<T> {
56         let mut min = Nothing;
57         for e in v {
58             min = Something(match min {
59                 Nothing => e,
60                 Something(n) => e.min(n)
61             });
62         }
63         min
64     }
65
66     /// We can compute the minimum of two integers
67     impl Minimum for i32 {
68         fn min(self, b: Self) -> Self {
69             if self < b { self } else { b }
70         }
71     }
72
73     /// Sample program to call vec_min
74     impl NumberOrNothing {
75         pub fn print(self) {
76             match self {
77                 Nothing => println!("The number is: <nothing>"),
78                 Something(n) => println!("The number is: {}", n),
79             };
80         }
81     }
82     fn read_vec() -> Vec<i32> {
83         vec![18,5,7,3,9,27]
84     }
85     pub fn main_i32() {
86         let vec = read_vec();
87         let min = vec_min(vec);
88         min.print();
89     }
90
91     // Now, all the same for calling it on f32
92     impl Minimum for f32 {
93         fn min(self, b: Self) -> Self {
94             if self < b { self } else { b }
95         }
96     }
97
98     impl SomethingOrNothing<f32> {
99         pub fn print_f32(self) {
100             match self {
101                 Nothing => println!("The number is: <nothing>"),
102                 Something(n) => println!("The number is: {}", n),
103             };
104         }
105     }
106
107     fn read_vec_f32() -> Vec<f32> {
108         vec![18.01,5.2,7.1,3.,9.2,27.123]
109     }
110     pub fn main_f32() {
111         let vec = read_vec_f32();
112         let min = vec_min(vec);
113         min.print_f32();
114     }
115
116     /// Add a `Display` implementation to `SomethingOrNothing`
117     use std::fmt;
118     impl<T: fmt::Display> fmt::Display for SomethingOrNothing<T> {
119         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120             match *self {
121                 Something(ref t) => t.fmt(f),
122                 Nothing          => "Nothing".fmt(f),
123             }
124         }
125     }
126 }
127