Merge pull request #41 from bzindovic/bzindovic-part13-clarity-fix
[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 part02 {
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
128 pub mod part03 {
129     use std::io::prelude::*;
130     use std::io;
131
132     fn read_vec() -> Vec<i32> {
133         let mut vec: Vec<i32> = Vec::<i32>::new();
134         let stdin = io::stdin();
135         println!("Enter a list of numbers, one per line. End with Ctrl-D (Linux) or Ctrl-Z (Windows).");
136         for line in stdin.lock().lines() {
137             let line = line.unwrap();
138             match line.trim().parse::<i32>() {
139                 Ok(num) => {
140                     vec.push(num)
141                 },
142                 // We don't care about the particular error, so we ignore it with a `_`.
143                 Err(_) => {
144                     println!("What did I say about numbers?")
145                 },
146             }
147         }
148
149         vec
150     }
151
152     use super::part02::{SomethingOrNothing,Something,Nothing,vec_min};
153
154     pub fn main() {
155         let vec = read_vec();
156         let min = vec_min(vec);
157         min.print2();
158     }
159
160     pub trait Print {
161         fn print(self);
162     }
163     impl Print for i32 {
164         fn print(self) {
165             print!("{}", self);
166         }
167     }
168
169     impl<T: Print> SomethingOrNothing<T> {
170         fn print2(self) {
171             match self {
172                 Nothing => println!("The number is: <nothing>"),
173                 Something(n) => {
174                     print!("The number is: ");
175                     n.print();
176                     println!();
177                 }
178             }
179         }
180     }
181
182     impl Print for f32 {
183         fn print(self) {
184             print!("{}", self);
185         }
186     }
187 }