1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-03-29 09:00:45 +02:00

Simplify generic min exercise ()

I was a bit dissatisfied with the test code for the generic min
exercise. We were supposed to be testing that the student wrote the
generic function correctly, but we only test their `min` function with
one type. I rewrote the exercise to test against multiple types, which
required that we use the regular `Ord` trait rather than a custom one. I
tend to prefer using the real items from `std` when we can because it's
a good way to get students familiar with the standard library. I also
removed the custom `Citation` type since it wasn't really important to
the exercise.
This commit is contained in:
Nicole L 2024-03-11 15:33:03 -07:00 committed by GitHub
parent 025fbffa99
commit d0656ca90b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 37 deletions

@ -5,12 +5,21 @@ minutes: 10
# Exercise: Generic `min`
In this short exercise, you will implement a generic `min` function that
determines the minimum of two values, using a `LessThan` trait.
determines the minimum of two values, using the [`Ord`] trait.
```rust,compile_fail
{{#include exercise.rs:LessThan}}
use std::cmp::Ordering;
// TODO: implement the `min` function used in `main`.
{{#include exercise.rs:main}}
```
<details>
- Show students the [`Ord`] trait and [`Ordering`] enum.
</details>
[`Ord`]: https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html
[`Ordering`]: https://doc.rust-lang.org/stable/std/cmp/enum.Ordering.html

@ -13,46 +13,24 @@
// limitations under the License.
// ANCHOR: solution
// ANCHOR: LessThan
trait LessThan {
/// Return true if self is less than other.
fn less_than(&self, other: &Self) -> bool;
}
use std::cmp::Ordering;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Citation {
author: &'static str,
year: u32,
}
impl LessThan for Citation {
fn less_than(&self, other: &Self) -> bool {
if self.author < other.author {
true
} else if self.author > other.author {
false
} else {
self.year < other.year
}
}
}
// ANCHOR_END: LessThan
fn min<T: LessThan>(l: T, r: T) -> T {
if l.less_than(&r) {
l
} else {
r
fn min<T: Ord>(l: T, r: T) -> T {
match l.cmp(&r) {
Ordering::Less | Ordering::Equal => l,
Ordering::Greater => r,
}
}
// ANCHOR: main
fn main() {
let cit1 = Citation { author: "Shapiro", year: 2011 };
let cit2 = Citation { author: "Baumann", year: 2010 };
let cit3 = Citation { author: "Baumann", year: 2019 };
debug_assert_eq!(min(cit1, cit2), cit2);
debug_assert_eq!(min(cit2, cit3), cit2);
debug_assert_eq!(min(cit1, cit3), cit3);
assert_eq!(min(0, 10), 0);
assert_eq!(min(500, 123), 123);
assert_eq!(min('a', 'z'), 'a');
assert_eq!(min('7', '1'), '1');
assert_eq!(min("hello", "goodbye"), "goodbye");
assert_eq!(min("bat", "armadillo"), "armadillo");
}
// ANCHOR_END: main